<!DOCTYPE HTML>
<html lang="zh-Hans" class="sidebar-visible no-js light">
    <head>
        <!-- Book generated using mdBook -->
        <meta charset="UTF-8">
        <title>Tour of Rust&#x27;s Standard Library Traits - Rust 优秀博文</title>


        <!-- Custom HTML head -->
        
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="theme-color" content="#ffffff" />

        <link rel="icon" href="../../favicon.svg">
        <link rel="shortcut icon" href="../../favicon.png">
        <link rel="stylesheet" href="../../css/variables.css">
        <link rel="stylesheet" href="../../css/general.css">
        <link rel="stylesheet" href="../../css/chrome.css">
        <link rel="stylesheet" href="../../css/print.css" media="print">

        <!-- Fonts -->
        <link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
        <link rel="stylesheet" href="../../fonts/fonts.css">

        <!-- Highlight.js Stylesheets -->
        <link rel="stylesheet" href="../../highlight.css">
        <link rel="stylesheet" href="../../tomorrow-night.css">
        <link rel="stylesheet" href="../../ayu-highlight.css">

        <!-- Custom theme stylesheets -->

    </head>
    <body>
        <!-- Provide site root to javascript -->
        <script type="text/javascript">
            var path_to_root = "../../";
            var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
        </script>

        <!-- Work around some values being stored in localStorage wrapped in quotes -->
        <script type="text/javascript">
            try {
                var theme = localStorage.getItem('mdbook-theme');
                var sidebar = localStorage.getItem('mdbook-sidebar');

                if (theme.startsWith('"') && theme.endsWith('"')) {
                    localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
                }

                if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
                    localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
                }
            } catch (e) { }
        </script>

        <!-- Set the theme before any content is loaded, prevents flash -->
        <script type="text/javascript">
            var theme;
            try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
            if (theme === null || theme === undefined) { theme = default_theme; }
            var html = document.querySelector('html');
            html.classList.remove('no-js')
            html.classList.remove('light')
            html.classList.add(theme);
            html.classList.add('js');
        </script>

        <!-- Hide / unhide sidebar before it is displayed -->
        <script type="text/javascript">
            var html = document.querySelector('html');
            var sidebar = 'hidden';
            if (document.body.clientWidth >= 1080) {
                try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
                sidebar = sidebar || 'visible';
            }
            html.classList.remove('sidebar-visible');
            html.classList.add("sidebar-" + sidebar);
        </script>

        <nav id="sidebar" class="sidebar" aria-label="Table of contents">
            <div class="sidebar-scrollbox">
                <ol class="chapter"><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">1.</strong> 类型系统</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../01_类型系统/Rust_Concept_Clarification_Deref_vs_AsRef_vs_Borrow_vs_Cow/Rust_Concept_Clarification_Deref_vs_AsRef_vs_Borrow_vs_Cow.html"><strong aria-hidden="true">1.1.</strong> Rust Concept Clarification Deref vs AsRef vs Borrow vs Cow</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/Rust_Concept_Clarification_Deref_vs_AsRef_vs_Borrow_vs_Cow/Deref_AsRef_Borrow_Cow释义.html"><strong aria-hidden="true">1.2.</strong> Deref AsRef Borrow Cow 释义</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/Rust的Borrow和AsRef：让你的代码用起来像呼吸一样自然/Rust的Borrow和AsRef：让你的代码用起来像呼吸一样自然.html"><strong aria-hidden="true">1.3.</strong> Rust的Borrow和AsRef：让你的代码用起来像呼吸一样自然</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/Rust的Cow类型有什么用？详解Cow及其用途/Rust的Cow类型有什么用？详解Cow及其用途.html"><strong aria-hidden="true">1.4.</strong> Rust的Cow类型有什么用？详解Cow及其用途</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/判别Fn、FnMut、FnOnce的标准/判别Fn、FnMut、FnOnce的标准.html"><strong aria-hidden="true">1.5.</strong> 判别Fn、FnMut、FnOnce的标准</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/一行代码告诉你内部可变性的真相(UnsafeCell)/一行代码告诉你内部可变性的真相(UnsafeCell).html"><strong aria-hidden="true">1.6.</strong> 一行代码告诉你内部可变性的真相(UnsafeCell)</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/Tour_of_Rust's_Standard_Library_Traits/Tour_of_Rust's_Standard_Library_Traits.html" class="active"><strong aria-hidden="true">1.7.</strong> Tour of Rust's Standard Library Traits</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/逆变、协变与子类型，以及Rust/逆变、协变与子类型，以及Rust.html"><strong aria-hidden="true">1.8.</strong> 逆变、协变与子类型，以及Rust</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/Rust自引用结构、Pin与Unpin/Rust自引用结构、Pin与Unpin.html"><strong aria-hidden="true">1.9.</strong> Rust自引用结构、Pin与Unpin</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/为什么Rust需要Pin,Unpin/为什么Rust需要Pin,Unpin.html"><strong aria-hidden="true">1.10.</strong> 译：为什么 Rust 需要 Pin, Unpin ？</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/定海神针Pin和Unpin/定海神针Pin和Unpin.html"><strong aria-hidden="true">1.11.</strong> 译：定海神针 Pin 和 Unpin</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/sizedness-in-rust/sizedness-in-rust.html"><strong aria-hidden="true">1.12.</strong> Sizedness in Rust</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/Rust生命周期集大成者PhantomData〈T〉/Rust生命周期集大成者PhantomData〈T〉.html"><strong aria-hidden="true">1.13.</strong> Rust生命周期集大成者 PhantomData&lt;T&gt;</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/数据库表达式执行的黑魔法：用Rust做类型体操/数据库表达式执行的黑魔法：用Rust做类型体操_Part_0.html"><strong aria-hidden="true">1.14.</strong> 数据库表达式执行的黑魔法：用Rust做类型体操 Part 0</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/数据库表达式执行的黑魔法：用Rust做类型体操/数据库表达式执行的黑魔法：GAT实现引用类型关联_Part_1.html"><strong aria-hidden="true">1.15.</strong> 数据库表达式执行的黑魔法：GAT实现引用类型关联 Part 1</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/数据库表达式执行的黑魔法：用Rust做类型体操/数据库表达式执行的黑魔法：用HRTB写bound_Part_2.html"><strong aria-hidden="true">1.16.</strong> 数据库表达式执行的黑魔法：用HRTB写bound Part 2</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/数据库表达式执行的黑魔法：用Rust做类型体操/数据库表达式执行的黑魔法：用Rust做类型体操之用宏展开重复代码_Part_3_&_4.html"><strong aria-hidden="true">1.17.</strong> 数据库表达式执行的黑魔法：用Rust做类型体操之用宏展开重复代码 Part 3 & 4</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/数据库表达式执行的黑魔法：用Rust做类型体操/数据库表达式执行的黑魔法：与Rust编译器斗智斗勇之表达式向量化_Part_5_&_6.html"><strong aria-hidden="true">1.18.</strong> 数据库表达式执行的黑魔法：与Rust编译器斗智斗勇之表达式向量化 Part 5 & 6</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/数据库表达式执行的黑魔法：用Rust做类型体操/数据库表达式执行的黑魔法：在Rust中用宏关联逻辑类型和实际类型_Part_7.html"><strong aria-hidden="true">1.19.</strong> 数据库表达式执行的黑魔法：在Rust中用宏关联逻辑类型和实际类型 Part 7</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">2.</strong> 生命周期</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../02_生命周期/Rust中的生命周期——从StrSplit实例说开去/Rust中的生命周期——从StrSplit实例说开去.html"><strong aria-hidden="true">2.1.</strong> Rust中的生命周期——从StrSplit实例说开去</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/与ChatGPT深度对话来学Rust生命周期/与ChatGPT深度对话来学Rust生命周期.html"><strong aria-hidden="true">2.2.</strong> 与ChatGPT深度对话来学Rust生命周期</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/进击的Rust生命周期——early_bound与late_bound（1）/进击的Rust生命周期——early_bound与late_bound（1）.html"><strong aria-hidden="true">2.3.</strong> 进击的Rust生命周期——early_bound与late_bound（1）</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/进击的Rust生命周期——early_bound与late_bound（2）/进击的Rust生命周期——early_bound与late_bound（2）.html"><strong aria-hidden="true">2.4.</strong> 进击的Rust生命周期——early_bound与late_bound（2）</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/进击的Rust生命周期——一力降十会的MIR（1）/进击的Rust生命周期——一力降十会的MIR（1）.html"><strong aria-hidden="true">2.5.</strong> 进击的Rust生命周期——一力降十会的MIR（1）</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/进击的Rust生命周期——一力降十会的MIR（2）/进击的Rust生命周期——一力降十会的MIR（2）.html"><strong aria-hidden="true">2.6.</strong> 进击的Rust生命周期——一力降十会的MIR（2）</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/Common_Rust_Lifetime_Misconceptions/Common_Rust_Lifetime_Misconceptions.html"><strong aria-hidden="true">2.7.</strong> Common Rust Lifetime Misconceptions</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/Rust生命周期常见误区/Rust生命周期常见误区.html"><strong aria-hidden="true">2.8.</strong> 译：Rust生命周期常见误区</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">3.</strong> 无畏并发</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../05_无畏并发/简单写个Rust无锁队列/简单写个Rust无锁队列.html"><strong aria-hidden="true">3.1.</strong> 简单写个Rust无锁队列</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/进击的Rust多线程——混合自旋锁/进击的Rust多线程——混合自旋锁.html"><strong aria-hidden="true">3.2.</strong> 进击的Rust多线程——混合自旋锁</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/An_unsafe_tour_of_Rust's_Send_and_Sync/An_unsafe_tour_of_Rust's_Send_and_Sync.html"><strong aria-hidden="true">3.3.</strong> An unsafe tour of Rust's Send and Sync</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/进击的Rust多线程——Send与Sync/进击的Rust多线程——Send与Sync.html"><strong aria-hidden="true">3.4.</strong> 进击的Rust多线程——Send与Sync</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/进击的Rust多线程——离经叛道的PhantomData/进击的Rust多线程——离经叛道的PhantomData.html"><strong aria-hidden="true">3.5.</strong> 进击的Rust多线程——离经叛道的PhantomData</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/Rust_Async_Pin概念解析/Rust_Async_Pin概念解析.html"><strong aria-hidden="true">3.6.</strong> Rust Async: Pin概念解析</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/Rust和C++的并发库对比/Rust和C++的并发库对比.html"><strong aria-hidden="true">3.7.</strong> 译：Rust 和 C++ 的并发库对比</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/Rust原子类型和内存排序/Rust原子类型和内存排序.html"><strong aria-hidden="true">3.8.</strong> Rust原子类型和内存排序</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">4.</strong> 网络编程</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../06_网络编程/从编解码层面理解WebSocket_手写一个WebSocket/从编解码层面理解WebSocket_手写一个WebSocket.html"><strong aria-hidden="true">4.1.</strong> 从编解码层面理解WebSocket 手写一 个WebSocket</a></li><li class="chapter-item expanded "><a href="../../06_网络编程/透过Rust探索系统的本原：网络篇/透过Rust探索系统的本原：网络篇.html"><strong aria-hidden="true">4.2.</strong> 透过Rust探索系统的本原：网络篇</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">5.</strong> 轮子系列</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../07_轮子系列/700行Rust写一个内存分配器/700行Rust写一个内存分配器.html"><strong aria-hidden="true">5.1.</strong> 700行Rust写一个内存分配器</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/Rust：网络库的实现思路/Rust：网络库的实现思路.html"><strong aria-hidden="true">5.2.</strong> Rust：网络库的实现思路</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/Rust异步运行时基础部件/Rust异步运行时基础部件.html"><strong aria-hidden="true">5.3.</strong> Rust异步运行时基础部件</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/使用Rust+epoll编写异步IO框架/使用Rust+epoll编写异步IO框架（1）.html"><strong aria-hidden="true">5.4.</strong> 使用Rust+epoll编写异步IO框架（1）</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/使用Rust+epoll编写异步IO框架/使用Rust+epoll编写异步IO框架（2）.html"><strong aria-hidden="true">5.5.</strong> 使用Rust+epoll编写异步IO框架（2）</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/使用Rust+epoll编写异步IO框架/使用Rust+epoll编写异步IO框架（3）.html"><strong aria-hidden="true">5.6.</strong> 使用Rust+epoll编写异步IO框架（3）</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/用rust从零开发一套web框架/用rust从零开发一套web框架：day1.html"><strong aria-hidden="true">5.7.</strong> 用rust从零开发一套web框架：day1</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/用rust从零开发一套web框架/用rust从零开发一套web框架：day2.html"><strong aria-hidden="true">5.8.</strong> 用rust从零开发一套web框架：day2</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/用rust从零开发一套web框架/用rust从零开发一套web框架：day3.html"><strong aria-hidden="true">5.9.</strong> 用rust从零开发一套web框架：day3</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/用rust从零开发一套web框架/用rust从零开发一套web框架：day4.html"><strong aria-hidden="true">5.10.</strong> 用rust从零开发一套web框架：day4</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/用rust从零开发一套web框架/用rust从零开发一套web框架：day5.html"><strong aria-hidden="true">5.11.</strong> 用rust从零开发一套web框架：day5</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">6.</strong> 奇技淫巧</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../08_奇技淫巧/Copy-On-Write是不是优化？/Copy-On-Write是不是优化？.html"><strong aria-hidden="true">6.1.</strong> 译：Copy-On-Write是不是优化？</a></li><li class="chapter-item expanded "><a href="../../08_奇技淫巧/揭秘神奇的Rust_Axum风格的函数实现/揭秘神奇的Rust_Axum风格的函数实现.html"><strong aria-hidden="true">6.2.</strong> 译：揭秘神奇的 Rust Axum 风格的函数实现</a></li><li class="chapter-item expanded "><a href="../../08_奇技淫巧/“变长参数”函数与回调/“变长参数”函数与回调.html"><strong aria-hidden="true">6.3.</strong> “变长参数”函数与回调</a></li><li class="chapter-item expanded "><a href="../../08_奇技淫巧/Rust字符串格式化的幕后：format_args!()/Rust字符串格式化的幕后：format_args!().html"><strong aria-hidden="true">6.4.</strong> 译：Rust字符串格式化的幕后：format_args!()</a></li><li class="chapter-item expanded "><a href="../../08_奇技淫巧/给Rust带来一点C++特产/给Rust带来一点C++特产.html"><strong aria-hidden="true">6.5.</strong> 给Rust带来一点C++特产</a></li><li class="chapter-item expanded "><a href="../../08_奇技淫巧/一步步实现_Rust_Bevy_ECS_的_System_简化版本/一步步实现_Rust_Bevy_ECS_的_System_简化版本.html"><strong aria-hidden="true">6.6.</strong> 一步步实现 Rust Bevy ECS 的 System 简化版本</a></li><li class="chapter-item expanded "><a href="../../08_奇技淫巧/Exploring_Design_Patterns_in_Rust_with_Algorithmic_Trading_Examples/Exploring_Design_Patterns_in_Rust_with_Algorithmic_Trading_Examples.html"><strong aria-hidden="true">6.7.</strong> Exploring Design Patterns in Rust with Algorithmic Trading Examples</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">7.</strong> 源码分析</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../09_源码分析/Rust并发：bytes源码分析/Rust并发：bytes源码分析.html"><strong aria-hidden="true">7.1.</strong> Rust并发：bytes源码分析</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Rust并发：标准库Arc源码分析/Rust并发：标准库Arc源码分析.html"><strong aria-hidden="true">7.2.</strong> Rust并发：标准库Arc源码分析</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Rust并发：标准库sync_Once源码分析/Rust并发：标准库sync_Once源码分析.html"><strong aria-hidden="true">7.3.</strong> Rust并发：标准库sync::Once源码分析</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Rust源码阅读：引用计数Rc/Rust源码阅读：引用计数Rc.html"><strong aria-hidden="true">7.4.</strong> Rust源码阅读：引用计数Rc</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Rust源码阅读：Cell、RefCell与内部可变性/Rust源码阅读：Cell、RefCell与内部可变性.html"><strong aria-hidden="true">7.5.</strong> Rust源码阅读： Cell、RefCell与内部可变性</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/关于_Rust_的_UnsafeCell、Cell_与_RefCell/关于_Rust_的_UnsafeCell、Cell_与_RefCell.html"><strong aria-hidden="true">7.6.</strong> 关于 Rust 的 UnsafeCell、Cell 与 RefCell</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Rust_Async_async-stream源码分析/Rust_Async_async-stream源码分析.html"><strong aria-hidden="true">7.7.</strong> Rust Async: async-stream源码分析</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/走进Tokio的异步世界/走进Tokio的异步世界.html"><strong aria-hidden="true">7.8.</strong> 走进 Tokio 的异步世界</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/tokio.rs_runtime的实现/tokio.rs_runtime的实现.html"><strong aria-hidden="true">7.9.</strong> tokio.rs runtime 的实现</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Tokio_internals/Tokio_internals.html"><strong aria-hidden="true">7.10.</strong> Tokio internals</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Tokio_internals/译文：Tokio內部机制.html"><strong aria-hidden="true">7.11.</strong> 译：Tokio 内部机制</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Rust_Axum_HTTP_框架的架构分析/Rust_Axum_HTTP_框架的架构分析.html"><strong aria-hidden="true">7.12.</strong> Rust Axum HTTP 框架的架构分析</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/安利一个Rust_Game_Engine：Bevy--ECS部分/安利一个Rust_Game_Engine：Bevy--ECS部分.html"><strong aria-hidden="true">7.13.</strong> 安利一个Rust Game Engine：Bevy--ECS部分</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Tokio_解析之任务调度/Tokio_解析之任务调度.html"><strong aria-hidden="true">7.14.</strong> Tokio 解析之任务调度</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">8.</strong> 生态观察</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../11_生态观察/Rust_web_frameworks_have_subpar_error_reporting/Rust_web_frameworks_have_subpar_error_reporting.html"><strong aria-hidden="true">8.1.</strong> Rust web frameworks have subpar error reporting</a></li><li class="chapter-item expanded "><a href="../../11_生态观察/SeaORM：要做Rust版本的ActiveRecord/SeaORM：要做Rust版本的ActiveRecord.html"><strong aria-hidden="true">8.2.</strong> SeaORM：要做Rust版本的ActiveRecord</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">9.</strong> 死灵终极</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_总述.html"><strong aria-hidden="true">9.1.</strong> 译：Learn Rust the Dangerous Way 总述</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_0.html"><strong aria-hidden="true">9.2.</strong> 译：Learn Rust the Dangerous Way 0</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_1.html"><strong aria-hidden="true">9.3.</strong> 译：Learn Rust the Dangerous Way 1</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_2.html"><strong aria-hidden="true">9.4.</strong> 译：Learn Rust the Dangerous Way 2</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_3.html"><strong aria-hidden="true">9.5.</strong> 译：Learn Rust the Dangerous Way 3</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_4.html"><strong aria-hidden="true">9.6.</strong> 译：Learn Rust the Dangerous Way 4</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_5.html"><strong aria-hidden="true">9.7.</strong> 译：Learn Rust the Dangerous Way 5</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Unsafe_Rust_随堂小测/Unsafe_Rust_随堂小测（一）.html"><strong aria-hidden="true">9.8.</strong> Unsafe Rust 随堂小测（一）</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Unsafe_Rust_随堂小测/Unsafe_Rust_随堂小测（二）.html"><strong aria-hidden="true">9.9.</strong> Unsafe Rust 随堂小测（二）</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Unsafe_Rust_随堂小测/Unsafe_Rust_随堂小测（三）.html"><strong aria-hidden="true">9.10.</strong> Unsafe Rust 随堂小测（三）</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Unsafe_Rust_随堂小测/Unsafe_Rust_随堂小测参考答案.html"><strong aria-hidden="true">9.11.</strong> Unsafe Rust 随堂小测参考答案</a></li></ol></li></ol>
            </div>
            <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
        </nav>

        <div id="page-wrapper" class="page-wrapper">

            <div class="page">
                                <div id="menu-bar-hover-placeholder"></div>
                <div id="menu-bar" class="menu-bar sticky bordered">
                    <div class="left-buttons">
                        <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
                            <i class="fa fa-bars"></i>
                        </button>
                        <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
                            <i class="fa fa-paint-brush"></i>
                        </button>
                        <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
                            <li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
                        </ul>
                        <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
                            <i class="fa fa-search"></i>
                        </button>
                    </div>

                    <h1 class="menu-title">Rust 优秀博文</h1>

                    <div class="right-buttons">
                        <a href="../../print.html" title="Print this book" aria-label="Print this book">
                            <i id="print-button" class="fa fa-print"></i>
                        </a>

                    </div>
                </div>

                <div id="search-wrapper" class="hidden">
                    <form id="searchbar-outer" class="searchbar-outer">
                        <input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
                    </form>
                    <div id="searchresults-outer" class="searchresults-outer hidden">
                        <div id="searchresults-header" class="searchresults-header"></div>
                        <ul id="searchresults">
                        </ul>
                    </div>
                </div>

                <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
                <script type="text/javascript">
                    document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
                    document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
                    Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
                        link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
                    });
                </script>

                <div id="content" class="content">
                    <main>
                        <h1 id="tour-of-rusts-standard-library-traits"><a class="header" href="#tour-of-rusts-standard-library-traits">Tour of Rust's Standard Library Traits</a></h1>
<p>作者：<a href="https://github.com/pretzelhammer">pretzelhammer</a></p>
<p>原载：<a href="https://github.com/pretzelhammer/rust-blog/blob/master/posts/tour-of-rusts-standard-library-traits.md">https://github.com/pretzelhammer/rust-blog/blob/master/posts/tour-of-rusts-standard-library-traits.md</a></p>
<p><em>31 March 2021 · #rust · #traits</em></p>
<p><strong>Table of Contents</strong></p>
<ul>
<li><a href="#intro">Intro</a></li>
<li><a href="#trait-basics">Trait Basics</a>
<ul>
<li><a href="#trait-items">Trait Items</a>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#functions">Functions</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#associated-types">Associated Types</a></li>
<li><a href="#generic-parameters">Generic Parameters</a></li>
<li><a href="#generic-types-vs-associated-types">Generic Types vs Associated Types</a></li>
</ul>
</li>
<li><a href="#scope">Scope</a></li>
<li><a href="#derive-macros">Derive Macros</a></li>
<li><a href="#default-impls">Default Impls</a></li>
<li><a href="#generic-blanket-impls">Generic Blanket Impls</a></li>
<li><a href="#subtraits--supertraits">Subtraits &amp; Supertraits</a></li>
<li><a href="#trait-objects">Trait Objects</a></li>
<li><a href="#marker-traits">Marker Traits</a></li>
<li><a href="#auto-traits">Auto Traits</a></li>
<li><a href="#unsafe-traits">Unsafe Traits</a></li>
</ul>
</li>
<li><a href="#auto-traits-1">Auto Traits</a>
<ul>
<li><a href="#send--sync">Send &amp; Sync</a></li>
<li><a href="#sized">Sized</a></li>
</ul>
</li>
<li><a href="#general-traits">General Traits</a>
<ul>
<li><a href="#default">Default</a></li>
<li><a href="#clone">Clone</a></li>
<li><a href="#copy">Copy</a></li>
<li><a href="#any">Any</a></li>
</ul>
</li>
<li><a href="#formatting-traits">Formatting Traits</a>
<ul>
<li><a href="#display--tostring">Display &amp; ToString</a></li>
<li><a href="#debug">Debug</a></li>
</ul>
</li>
<li><a href="#operator-traits">Operator Traits</a>
<ul>
<li><a href="#comparison-traits">Comparison Traits</a>
<ul>
<li><a href="#partialeq--eq">PartialEq &amp; Eq</a></li>
<li><a href="#hash">Hash</a></li>
<li><a href="#partialord--ord">PartialOrd &amp; Ord</a></li>
</ul>
</li>
<li><a href="#arithmetic-traits">Arithmetic Traits</a>
<ul>
<li><a href="#add--addassign">Add &amp; AddAssign</a></li>
</ul>
</li>
<li><a href="#closure-traits">Closure Traits</a>
<ul>
<li><a href="#fnonce-fnmut--fn">FnOnce, FnMut, &amp; Fn</a></li>
</ul>
</li>
<li><a href="#other-traits">Other Traits</a>
<ul>
<li><a href="#deref--derefmut">Deref &amp; DerefMut</a></li>
<li><a href="#index--indexmut">Index &amp; IndexMut</a></li>
<li><a href="#drop">Drop</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#conversion-traits">Conversion Traits</a>
<ul>
<li><a href="#from--into">From &amp; Into</a></li>
</ul>
</li>
<li><a href="#error-handling">Error Handling</a>
<ul>
<li><a href="#error">Error</a></li>
</ul>
</li>
<li><a href="#conversion-traits-continued">Conversion Traits Continued</a>
<ul>
<li><a href="#tryfrom--tryinto">TryFrom &amp; TryInto</a></li>
<li><a href="#fromstr">FromStr</a></li>
<li><a href="#asref--asmut">AsRef &amp; AsMut</a></li>
<li><a href="#borrow--borrowmut">Borrow &amp; BorrowMut</a></li>
<li><a href="#toowned">ToOwned</a></li>
</ul>
</li>
<li><a href="#iteration-traits">Iteration Traits</a>
<ul>
<li><a href="#iterator">Iterator</a></li>
<li><a href="#intoiterator">IntoIterator</a></li>
<li><a href="#fromiterator">FromIterator</a></li>
</ul>
</li>
<li><a href="#io-traits">I/O Traits</a>
<ul>
<li><a href="#read--write">Read &amp; Write</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
<li><a href="#discuss">Discuss</a></li>
<li><a href="#notifications">Notifications</a></li>
<li><a href="#further-reading">Further Reading</a></li>
</ul>
<h2 id="intro"><a class="header" href="#intro">Intro</a></h2>
<p>Have you ever wondered what's the difference between:</p>
<ul>
<li><code>Deref&lt;Target = T&gt;</code>, <code>AsRef&lt;T&gt;</code>, and <code>Borrow&lt;T&gt;</code>?</li>
<li><code>Clone</code>, <code>Copy</code>, and <code>ToOwned</code>?</li>
<li><code>From&lt;T&gt;</code> and <code>Into&lt;T&gt;</code>?</li>
<li><code>TryFrom&lt;&amp;str&gt;</code> and <code>FromStr</code>?</li>
<li><code>FnOnce</code>, <code>FnMut</code>, <code>Fn</code>, and <code>fn</code>?</li>
</ul>
<p>Or ever asked yourself the questions:</p>
<ul>
<li><em>&quot;When do I use associated types vs generic types in my trait?&quot;</em></li>
<li><em>&quot;What are generic blanket impls?&quot;</em></li>
<li><em>&quot;How do subtraits and supertraits work?&quot;</em></li>
<li><em>&quot;Why does this trait not have any methods?&quot;</em></li>
</ul>
<p>Well then this is the article for you! It answers all of the above questions and much much more. Together we'll do a quick flyby tour of all of the most popular and commonly used traits from the Rust standard library!</p>
<p>You can read this article in order section by section or jump around to whichever traits interest you the most because each trait section begins with a list of links to <strong>Prerequisite</strong> sections that you should read to have adequate context to understand the current section's explanations.</p>
<h2 id="trait-basics"><a class="header" href="#trait-basics">Trait Basics</a></h2>
<p>We'll cover just enough of the basics so that the rest of the article can be streamlined without having to repeat the same explanations of the same concepts over and over as they reappear in different traits.</p>
<h3 id="trait-items"><a class="header" href="#trait-items">Trait Items</a></h3>
<p>Trait items are any items that are part of a trait declaration.</p>
<h4 id="self"><a class="header" href="#self">Self</a></h4>
<p><code>Self</code> always refers to the implementing type.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Trait {
    // always returns i32
    fn returns_num() -&gt; i32;

    // returns implementing type
    fn returns_self() -&gt; Self;
}

struct SomeType;
struct OtherType;

impl Trait for SomeType {
    fn returns_num() -&gt; i32 {
        5
    }

    // Self == SomeType
    fn returns_self() -&gt; Self {
        SomeType
    }
}

impl Trait for OtherType {
    fn returns_num() -&gt; i32 {
        6
    }

    // Self == OtherType
    fn returns_self() -&gt; Self {
        OtherType
    }
}
<span class="boring">}
</span></code></pre></pre>
<h4 id="functions"><a class="header" href="#functions">Functions</a></h4>
<p>A trait function is any function whose first parameter does not use the <code>self</code> keyword.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Default {
    // function
    fn default() -&gt; Self;
}
<span class="boring">}
</span></code></pre></pre>
<p>Trait functions can be called namespaced by the trait or implementing type:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    let zero: i32 = Default::default();
    let zero = i32::default();
}
</code></pre></pre>
<h4 id="methods"><a class="header" href="#methods">Methods</a></h4>
<p>A trait method is any function whose first parameter uses the <code>self</code> keyword and is of type <code>Self</code>, <code>&amp;Self</code>, <code>&amp;mut Self</code>. The former types can also be wrapped with a <code>Box</code>, <code>Rc</code>, <code>Arc</code>, or <code>Pin</code>.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Trait {
    // methods
    fn takes_self(self);
    fn takes_immut_self(&amp;self);
    fn takes_mut_self(&amp;mut self);

    // above methods desugared
    fn takes_self(self: Self);
    fn takes_immut_self(self: &amp;Self);
    fn takes_mut_self(self: &amp;mut Self);
}

// example from standard library
trait ToString {
    fn to_string(&amp;self) -&gt; String;
}
<span class="boring">}
</span></code></pre></pre>
<p>Methods can be called using the dot operator on the implementing type:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    let five = 5.to_string();
}
</code></pre></pre>
<p>However, similarly to functions, they can also be called namespaced by the trait or implementing type:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    let five = ToString::to_string(&amp;5);
    let five = i32::to_string(&amp;5);
}
</code></pre></pre>
<h4 id="associated-types"><a class="header" href="#associated-types">Associated Types</a></h4>
<p>A trait can have associated types. This is useful when we need to use some type other than <code>Self</code> within function signatures but would still like the type to be chosen by the implementer rather than being hardcoded in the trait declaration:</p>
<pre><pre class="playground"><code class="language-rust">trait Trait {
    type AssociatedType;
    fn func(arg: Self::AssociatedType);
}

struct SomeType;
struct OtherType;

// any type implementing Trait can
// choose the type of AssociatedType

impl Trait for SomeType {
    type AssociatedType = i8; // chooses i8
    fn func(arg: Self::AssociatedType) {}
}

impl Trait for OtherType {
    type AssociatedType = u8; // chooses u8
    fn func(arg: Self::AssociatedType) {}
}

fn main() {
    SomeType::func(-1_i8); // can only call func with i8 on SomeType
    OtherType::func(1_u8); // can only call func with u8 on OtherType
}
</code></pre></pre>
<h4 id="generic-parameters"><a class="header" href="#generic-parameters">Generic Parameters</a></h4>
<p><em>&quot;Generic parameters&quot;</em> broadly refers to generic type parameters, generic lifetime parameters, and generic const parameters. Since all of those are a mouthful to say people commonly abbreviate them to <em>&quot;generic types&quot;</em>, <em>&quot;lifetimes&quot;</em>, and <em>&quot;generic consts&quot;</em>. Since generic consts are not used in any of the standard library traits we'll be covering they're outside the scope of this article.</p>
<p>We can generalize a trait declaration using parameters:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// trait declaration generalized with lifetime &amp; type parameters
trait Trait&lt;'a, T&gt; {
    // signature uses generic type
    fn func1(arg: T);
    
    // signature uses lifetime
    fn func2(arg: &amp;'a i32);
    
    // signature uses generic type &amp; lifetime
    fn func3(arg: &amp;'a T);
}

struct SomeType;

impl&lt;'a&gt; Trait&lt;'a, i8&gt; for SomeType {
    fn func1(arg: i8) {}
    fn func2(arg: &amp;'a i32) {}
    fn func3(arg: &amp;'a i8) {}
}

impl&lt;'b&gt; Trait&lt;'b, u8&gt; for SomeType {
    fn func1(arg: u8) {}
    fn func2(arg: &amp;'b i32) {}
    fn func3(arg: &amp;'b u8) {}
}
<span class="boring">}
</span></code></pre></pre>
<p>It's possible to provide default values for generic types. The most commonly used default value is <code>Self</code> but any type works:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// make T = Self by default
trait Trait&lt;T = Self&gt; {
    fn func(t: T) {}
}

// any type can be used as the default
trait Trait2&lt;T = i32&gt; {
    fn func2(t: T) {}
}

struct SomeType;

// omitting the generic type will
// cause the impl to use the default
// value, which is Self here
impl Trait for SomeType {
    fn func(t: SomeType) {}
}

// default value here is i32
impl Trait2 for SomeType {
    fn func2(t: i32) {}
}

// the default is overridable as we'd expect
impl Trait&lt;String&gt; for SomeType {
    fn func(t: String) {}
}

// overridable here too
impl Trait2&lt;String&gt; for SomeType {
    fn func2(t: String) {}
}
<span class="boring">}
</span></code></pre></pre>
<p>Aside from parameterizing the trait it's also possible to parameterize individual functions and methods:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Trait {
    fn func&lt;'a, T&gt;(t: &amp;'a T);
}
<span class="boring">}
</span></code></pre></pre>
<h4 id="generic-types-vs-associated-types"><a class="header" href="#generic-types-vs-associated-types">Generic Types vs Associated Types</a></h4>
<p>Both generic types and associated types defer the decision to the implementer on which concrete types should be used in the trait's functions and methods, so this section seeks to explain when to use one over the other.</p>
<p>The general rule-of-thumb is:</p>
<ul>
<li>Use associated types when there should only be a single impl of the trait per type.</li>
<li>Use generic types when there can be many possible impls of the trait per type.</li>
</ul>
<p>Let's say we want to define a trait called <code>Add</code> which allows us to add values together. Here's an initial design and impl that only uses associated types:</p>
<pre><pre class="playground"><code class="language-rust">trait Add {
    type Rhs;
    type Output;
    fn add(self, rhs: Self::Rhs) -&gt; Self::Output;
}

struct Point {
    x: i32,
    y: i32,
}

impl Add for Point {
    type Rhs = Point;
    type Output = Point;
    fn add(self, rhs: Point) -&gt; Point {
        Point {
            x: self.x + rhs.x,
            y: self.y + rhs.y,
        }
    }
}

fn main() {
    let p1 = Point { x: 1, y: 1 };
    let p2 = Point { x: 2, y: 2 };
    let p3 = p1.add(p2);
    assert_eq!(p3.x, 3);
    assert_eq!(p3.y, 3);
}
</code></pre></pre>
<p>Let's say we wanted to add the ability to add <code>i32</code>s to <code>Point</code>s where the <code>i32</code> would be added to both the <code>x</code> and <code>y</code> members:</p>
<pre><pre class="playground"><code class="language-rust">trait Add {
    type Rhs;
    type Output;
    fn add(self, rhs: Self::Rhs) -&gt; Self::Output;
}

struct Point {
    x: i32,
    y: i32,
}

impl Add for Point {
    type Rhs = Point;
    type Output = Point;
    fn add(self, rhs: Point) -&gt; Point {
        Point {
            x: self.x + rhs.x,
            y: self.y + rhs.y,
        }
    }
}

impl Add for Point { // ❌
    type Rhs = i32;
    type Output = Point;
    fn add(self, rhs: i32) -&gt; Point {
        Point {
            x: self.x + rhs,
            y: self.y + rhs,
        }
    }
}

fn main() {
    let p1 = Point { x: 1, y: 1 };
    let p2 = Point { x: 2, y: 2 };
    let p3 = p1.add(p2);
    assert_eq!(p3.x, 3);
    assert_eq!(p3.y, 3);
    
    let p1 = Point { x: 1, y: 1 };
    let int2 = 2;
    let p3 = p1.add(int2); // ❌
    assert_eq!(p3.x, 3);
    assert_eq!(p3.y, 3);
}
</code></pre></pre>
<p>Throws:</p>
<pre><code class="language-none">error[E0119]: conflicting implementations of trait `Add` for type `Point`:
  --&gt; src/main.rs:23:1
   |
12 | impl Add for Point {
   | ------------------ first implementation here
...
23 | impl Add for Point {
   | ^^^^^^^^^^^^^^^^^^ conflicting implementation for `Point`
</code></pre>
<p>Since the <code>Add</code> trait is not parameterized by any generic types we can only impl it once per type, which means we can only pick the types for both <code>Rhs</code> and <code>Output</code> once! To allow adding both <code>Points</code>s and <code>i32</code>s to <code>Point</code> we have to refactor <code>Rhs</code> from an associated type to a generic type, which would allow us to impl the trait multiple times for <code>Point</code> with different type arguments for <code>Rhs</code>:</p>
<pre><pre class="playground"><code class="language-rust">trait Add&lt;Rhs&gt; {
    type Output;
    fn add(self, rhs: Rhs) -&gt; Self::Output;
}

struct Point {
    x: i32,
    y: i32,
}

impl Add&lt;Point&gt; for Point {
    type Output = Self;
    fn add(self, rhs: Point) -&gt; Self::Output {
        Point {
            x: self.x + rhs.x,
            y: self.y + rhs.y,
        }
    }
}

impl Add&lt;i32&gt; for Point { // ✅
    type Output = Self;
    fn add(self, rhs: i32) -&gt; Self::Output {
        Point {
            x: self.x + rhs,
            y: self.y + rhs,
        }
    }
}

fn main() {
    let p1 = Point { x: 1, y: 1 };
    let p2 = Point { x: 2, y: 2 };
    let p3 = p1.add(p2);
    assert_eq!(p3.x, 3);
    assert_eq!(p3.y, 3);
    
    let p1 = Point { x: 1, y: 1 };
    let int2 = 2;
    let p3 = p1.add(int2); // ✅
    assert_eq!(p3.x, 3);
    assert_eq!(p3.y, 3);
}
</code></pre></pre>
<p>Let's say we add a new type called <code>Line</code> which contains two <code>Point</code>s, and now there are contexts within our program where adding two <code>Point</code>s should produce a <code>Line</code> instead of a <code>Point</code>. This is not possible given the current design of the <code>Add</code> trait where <code>Output</code> is an associated type but we can satisfy these new requirements by refactoring <code>Output</code> from an associated type into a generic type:</p>
<pre><pre class="playground"><code class="language-rust">trait Add&lt;Rhs, Output&gt; {
    fn add(self, rhs: Rhs) -&gt; Output;
}

struct Point {
    x: i32,
    y: i32,
}

impl Add&lt;Point, Point&gt; for Point {
    fn add(self, rhs: Point) -&gt; Point {
        Point {
            x: self.x + rhs.x,
            y: self.y + rhs.y,
        }
    }
}

impl Add&lt;i32, Point&gt; for Point {
    fn add(self, rhs: i32) -&gt; Point {
        Point {
            x: self.x + rhs,
            y: self.y + rhs,
        }
    }
}

struct Line {
    start: Point,
    end: Point,
}

impl Add&lt;Point, Line&gt; for Point { // ✅
    fn add(self, rhs: Point) -&gt; Line {
        Line {
            start: self,
            end: rhs,
        }
    }
}

fn main() {
    let p1 = Point { x: 1, y: 1 };
    let p2 = Point { x: 2, y: 2 };
    let p3: Point = p1.add(p2);
    assert!(p3.x == 3 &amp;&amp; p3.y == 3);

    let p1 = Point { x: 1, y: 1 };
    let int2 = 2;
    let p3 = p1.add(int2);
    assert!(p3.x == 3 &amp;&amp; p3.y == 3);

    let p1 = Point { x: 1, y: 1 };
    let p2 = Point { x: 2, y: 2 };
    let l: Line = p1.add(p2); // ✅
    assert!(l.start.x == 1 &amp;&amp; l.start.y == 1 &amp;&amp; l.end.x == 2 &amp;&amp; l.end.y == 2)
}
</code></pre></pre>
<p>So which <code>Add</code> trait above is the best? It really depends on the requirements of your program! They're all good in the right situations.</p>
<h3 id="scope"><a class="header" href="#scope">Scope</a></h3>
<p>Trait items cannot be used unless the trait is in scope. Most Rustaceans learn this the hard way the first time they try to write a program that does anything with I/O because the <code>Read</code> and <code>Write</code> traits are not in the standard library prelude:</p>
<pre><pre class="playground"><code class="language-rust">use std::fs::File;
use std::io;

fn main() -&gt; Result&lt;(), io::Error&gt; {
    let mut file = File::open(&quot;Cargo.toml&quot;)?;
    let mut buffer = String::new();
    file.read_to_string(&amp;mut buffer)?; // ❌ read_to_string not found in File
    Ok(())
}
</code></pre></pre>
<p><code>read_to_string(buf: &amp;mut String)</code> is declared by the <code>std::io::Read</code> trait and implemented by the <code>std::fs::File</code> struct but in order to call it <code>std::io::Read</code> must be in scope:</p>
<pre><pre class="playground"><code class="language-rust">use std::fs::File;
use std::io;
use std::io::Read; // ✅

fn main() -&gt; Result&lt;(), io::Error&gt; {
    let mut file = File::open(&quot;Cargo.toml&quot;)?;
    let mut buffer = String::new();
    file.read_to_string(&amp;mut buffer)?; // ✅
    Ok(())
}
</code></pre></pre>
<p>The standard library prelude is a module in the standard library, i.e. <code>std::prelude::v1</code>, that gets auto imported at the top of every other module, i.e. <code>use std::prelude::v1::*</code>. Thus the following traits are always in scope and we never have to explicitly import them ourselves because they're part of the prelude:</p>
<ul>
<li><a href="#asref--asmut">AsMut</a></li>
<li><a href="#asref--asmut">AsRef</a></li>
<li><a href="#clone">Clone</a></li>
<li><a href="#copy">Copy</a></li>
<li><a href="#default">Default</a></li>
<li><a href="#drop">Drop</a></li>
<li><a href="#partialeq--eq">Eq</a></li>
<li><a href="#fnonce-fnmut--fn">Fn</a></li>
<li><a href="#fnonce-fnmut--fn">FnMut</a></li>
<li><a href="#fnonce-fnmut--fn">FnOnce</a></li>
<li><a href="#from--into">From</a></li>
<li><a href="#from--into">Into</a></li>
<li><a href="#toowned">ToOwned</a></li>
<li><a href="#intoiterator">IntoIterator</a></li>
<li><a href="#iterator">Iterator</a></li>
<li><a href="#partialeq--eq">PartialEq</a></li>
<li><a href="#partialord--ord">PartialOrd</a></li>
<li><a href="#send--sync">Send</a></li>
<li><a href="#sized">Sized</a></li>
<li><a href="#send--sync">Sync</a></li>
<li><a href="#display--tostring">ToString</a></li>
<li><a href="#partialord--ord">Ord</a></li>
</ul>
<h3 id="derive-macros"><a class="header" href="#derive-macros">Derive Macros</a></h3>
<p>The standard library exports a handful of derive macros which we can use to quickly and conveniently impl a trait on a type if all of its members also impl the trait. The derive macros are named after the traits they impl:</p>
<ul>
<li><a href="#clone">Clone</a></li>
<li><a href="#copy">Copy</a></li>
<li><a href="#debug">Debug</a></li>
<li><a href="#default">Default</a></li>
<li><a href="#partialeq--eq">Eq</a></li>
<li><a href="#hash">Hash</a></li>
<li><a href="#partialord--ord">Ord</a></li>
<li><a href="#partialeq--eq">PartialEq</a></li>
<li><a href="#partialord--ord">PartialOrd</a></li>
</ul>
<p>Example usage:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// macro derives Copy &amp; Clone impl for SomeType
#[derive(Copy, Clone)]
struct SomeType;
<span class="boring">}
</span></code></pre></pre>
<p>Note: derive macros are just procedural macros and can do anything, there's no hard rule that they must impl a trait or that they can only work if all the members of the type impl a trait, these are just the conventions followed by the derive macros in the standard library.</p>
<h3 id="default-impls"><a class="header" href="#default-impls">Default Impls</a></h3>
<p>Traits can provide default impls for their functions and methods.</p>
<pre><pre class="playground"><code class="language-rust">trait Trait {
    fn method(&amp;self) {
        println!(&quot;default impl&quot;);
    }
}

struct SomeType;
struct OtherType;

// use default impl for Trait::method
impl Trait for SomeType {}

impl Trait for OtherType {
    // use our own impl for Trait::method
    fn method(&amp;self) {
        println!(&quot;OtherType impl&quot;);
    }
}

fn main() {
    SomeType.method(); // prints &quot;default impl&quot;
    OtherType.method(); // prints &quot;OtherType impl&quot;
}
</code></pre></pre>
<p>This is especially handy if some of the trait methods can be implemented solely using other trait methods.</p>
<pre><pre class="playground"><code class="language-rust">trait Greet {
    fn greet(&amp;self, name: &amp;str) -&gt; String;
    fn greet_loudly(&amp;self, name: &amp;str) -&gt; String {
        self.greet(name) + &quot;!&quot;
    }
}

struct Hello;
struct Hola;

impl Greet for Hello {
    fn greet(&amp;self, name: &amp;str) -&gt; String {
        format!(&quot;Hello {}&quot;, name)
    }
    // use default impl for greet_loudly
}

impl Greet for Hola {
    fn greet(&amp;self, name: &amp;str) -&gt; String {
        format!(&quot;Hola {}&quot;, name)
    }
    // override default impl
    fn greet_loudly(&amp;self, name: &amp;str) -&gt; String {
        let mut greeting = self.greet(name);
        greeting.insert_str(0, &quot;¡&quot;);
        greeting + &quot;!&quot;
    }
}

fn main() {
    println!(&quot;{}&quot;, Hello.greet(&quot;John&quot;)); // prints &quot;Hello John&quot;
    println!(&quot;{}&quot;, Hello.greet_loudly(&quot;John&quot;)); // prints &quot;Hello John!&quot;
    println!(&quot;{}&quot;, Hola.greet(&quot;John&quot;)); // prints &quot;Hola John&quot;
    println!(&quot;{}&quot;, Hola.greet_loudly(&quot;John&quot;)); // prints &quot;¡Hola John!&quot;
}
</code></pre></pre>
<p>Many traits in the standard library provide default impls for many of their methods.</p>
<h3 id="generic-blanket-impls"><a class="header" href="#generic-blanket-impls">Generic Blanket Impls</a></h3>
<p>A generic blanket impl is an impl on a generic type instead of a concrete type. To explain why and how we'd use one let's start by writing an <code>is_even</code> method for number types:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Even {
    fn is_even(self) -&gt; bool;
}

impl Even for i8 {
    fn is_even(self) -&gt; bool {
        self % 2_i8 == 0_i8
    }
}

impl Even for u8 {
    fn is_even(self) -&gt; bool {
        self % 2_u8 == 0_u8
    }
}

impl Even for i16 {
    fn is_even(self) -&gt; bool {
        self % 2_i16 == 0_i16
    }
}

// etc

#[test] // ✅
fn test_is_even() {
    assert!(2_i8.is_even());
    assert!(4_u8.is_even());
    assert!(6_i16.is_even());
    // etc
}
<span class="boring">}
</span></code></pre></pre>
<p>Obviously, this is very verbose. Also, all of our impls are almost identical. Furthermore, in the unlikely but still possible event that Rust decides to add more number types in the future we have to remember to come back to this code and update it with the new number types. We can solve all these problems using a generic blanket impl:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::fmt::Debug;
use std::convert::TryInto;
use std::ops::Rem;

trait Even {
    fn is_even(self) -&gt; bool;
}

// generic blanket impl
impl&lt;T&gt; Even for T
where
    T: Rem&lt;Output = T&gt; + PartialEq&lt;T&gt; + Sized,
    u8: TryInto&lt;T&gt;,
    &lt;u8 as TryInto&lt;T&gt;&gt;::Error: Debug,
{
    fn is_even(self) -&gt; bool {
        // these unwraps will never panic
        self % 2.try_into().unwrap() == 0.try_into().unwrap()
    }
}

#[test] // ✅
fn test_is_even() {
    assert!(2_i8.is_even());
    assert!(4_u8.is_even());
    assert!(6_i16.is_even());
    // etc
}
<span class="boring">}
</span></code></pre></pre>
<p>Unlike default impls, which provide <em>an</em> impl, generic blanket impls provide <em>the</em> impl, so they are not overridable.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::fmt::Debug;
use std::convert::TryInto;
use std::ops::Rem;

trait Even {
    fn is_even(self) -&gt; bool;
}

impl&lt;T&gt; Even for T
where
    T: Rem&lt;Output = T&gt; + PartialEq&lt;T&gt; + Sized,
    u8: TryInto&lt;T&gt;,
    &lt;u8 as TryInto&lt;T&gt;&gt;::Error: Debug,
{
    fn is_even(self) -&gt; bool {
        self % 2.try_into().unwrap() == 0.try_into().unwrap()
    }
}

impl Even for u8 { // ❌
    fn is_even(self) -&gt; bool {
        self % 2_u8 == 0_u8
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>Throws:</p>
<pre><code class="language-none">error[E0119]: conflicting implementations of trait `Even` for type `u8`:
  --&gt; src/lib.rs:22:1
   |
10 | / impl&lt;T&gt; Even for T
11 | | where
12 | |     T: Rem&lt;Output = T&gt; + PartialEq&lt;T&gt; + Sized,
13 | |     u8: TryInto&lt;T&gt;,
...  |
19 | |     }
20 | | }
   | |_- first implementation here
21 | 
22 |   impl Even for u8 {
   |   ^^^^^^^^^^^^^^^^ conflicting implementation for `u8`
</code></pre>
<p>These impls overlap, hence they conflict, hence Rust rejects the code to ensure trait coherence. Trait coherence is the property that there exists at most one impl of a trait for any given type. The rules Rust uses to enforce trait coherence, the implications of those rules, and workarounds for the implications are outside the scope of this article.</p>
<h3 id="subtraits--supertraits"><a class="header" href="#subtraits--supertraits">Subtraits &amp; Supertraits</a></h3>
<p>The &quot;sub&quot; in &quot;subtrait&quot; refers to subset and the &quot;super&quot; in &quot;supertrait&quot; refers to superset. If we have this trait declaration:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Subtrait: Supertrait {}
<span class="boring">}
</span></code></pre></pre>
<p>All of the types which impl <code>Subtrait</code> are a subset of all the types which impl <code>Supertrait</code>, or to put it in opposite but equivalent terms: all the types which impl <code>Supertrait</code> are a superset of all the types which impl <code>Subtrait</code>.</p>
<p>Also, the above is just syntax sugar for:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Subtrait where Self: Supertrait {}
<span class="boring">}
</span></code></pre></pre>
<p>It's a subtle yet important distinction to understand that the bound is on <code>Self</code>, i.e. the type impling <code>Subtrait</code>, and not on <code>Subtrait</code> itself. The latter would not make any sense, since trait bounds can only be applied to concrete types which can impl traits. Traits cannot impl other traits:</p>
<pre><pre class="playground"><code class="language-rust">trait Supertrait {
    fn method(&amp;self) {
        println!(&quot;in supertrait&quot;);
    }
}

trait Subtrait: Supertrait {
    // this looks like it might impl or
    // override Supertrait::method but it
    // does not
    fn method(&amp;self) {
        println!(&quot;in subtrait&quot;)
    }
}

struct SomeType;

// adds Supertrait::method to SomeType
impl Supertrait for SomeType {}

// adds Subtrait::method to SomeType
impl Subtrait for SomeType {}

// both methods exist on SomeType simultaneously
// neither overriding or shadowing the other

fn main() {
    SomeType.method(); // ❌ ambiguous method call
    // must disambiguate using fully-qualified syntax
    &lt;SomeType as Supertrait&gt;::method(&amp;SomeType); // ✅ prints &quot;in supertrait&quot;
    &lt;SomeType as Subtrait&gt;::method(&amp;SomeType); // ✅ prints &quot;in subtrait&quot;
}
</code></pre></pre>
<p>Furthermore, there are no rules for how a type must impl both a subtrait and a supertrait. It can use the methods from either in the impl of the other.</p>
<pre><pre class="playground"><code class="language-rust">trait Supertrait {
    fn super_method(&amp;mut self);
}

trait Subtrait: Supertrait {
    fn sub_method(&amp;mut self);
}

struct CallSuperFromSub;

impl Supertrait for CallSuperFromSub {
    fn super_method(&amp;mut self) {
        println!(&quot;in super&quot;);
    }
}

impl Subtrait for CallSuperFromSub {
    fn sub_method(&amp;mut self) {
        println!(&quot;in sub&quot;);
        self.super_method();
    }
}

struct CallSubFromSuper;

impl Supertrait for CallSubFromSuper {
    fn super_method(&amp;mut self) {
        println!(&quot;in super&quot;);
        self.sub_method();
    }
}

impl Subtrait for CallSubFromSuper {
    fn sub_method(&amp;mut self) {
        println!(&quot;in sub&quot;);
    }
}

struct CallEachOther(bool);

impl Supertrait for CallEachOther {
    fn super_method(&amp;mut self) {
        println!(&quot;in super&quot;);
        if self.0 {
            self.0 = false;
            self.sub_method();
        }
    }
}

impl Subtrait for CallEachOther {
    fn sub_method(&amp;mut self) {
        println!(&quot;in sub&quot;);
        if self.0 {
            self.0 = false;
            self.super_method();
        }
    }
}

fn main() {
    CallSuperFromSub.super_method(); // prints &quot;in super&quot;
    CallSuperFromSub.sub_method(); // prints &quot;in sub&quot;, &quot;in super&quot;
    
    CallSubFromSuper.super_method(); // prints &quot;in super&quot;, &quot;in sub&quot;
    CallSubFromSuper.sub_method(); // prints &quot;in sub&quot;
    
    CallEachOther(true).super_method(); // prints &quot;in super&quot;, &quot;in sub&quot;
    CallEachOther(true).sub_method(); // prints &quot;in sub&quot;, &quot;in super&quot;
}
</code></pre></pre>
<p>Hopefully the examples above show that the relationship between subtraits and supertraits can be complex. Before introducing a mental model that neatly encapsulates all of that complexity let's quickly review and establish the mental model we use for understanding trait bounds on generic types:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn function&lt;T: Clone&gt;(t: T) {
    // impl
}
<span class="boring">}
</span></code></pre></pre>
<p>Without knowing anything about the impl of this function we could reasonably guess that <code>t.clone()</code> gets called at some point because when a generic type is bounded by a trait that strongly implies it has a dependency on the trait. The mental model for understanding the relationship between generic types and their trait bounds is a simple and intuitive one: generic types <em>depend on</em> their trait bounds.</p>
<p>Now let's look the trait declaration for <code>Copy</code>:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Copy: Clone {}
<span class="boring">}
</span></code></pre></pre>
<p>The syntax above looks very similar to the syntax for applying a trait bound on a generic type and yet <code>Copy</code> doesn't depend on <code>Clone</code> at all. The mental model we developed earlier doesn't help us here. In my opinion, the most simple and elegant mental model for understanding the relationship between subtraits and supertraits is: subtraits <em>refine</em> their supertraits.</p>
<p>&quot;Refinement&quot; is intentionally kept somewhat vague because it can mean different things in different contexts:</p>
<ul>
<li>a subtrait might make its supertrait's methods' impls more specialized, faster, use less memory, e.g. <code>Copy: Clone</code></li>
<li>a subtrait might make additional guarantees about the supertrait's methods' impls, e.g. <code>Eq: PartialEq</code>, <code>Ord: PartialOrd</code>, <code>ExactSizeIterator: Iterator</code></li>
<li>a subtrait might make the supertrait's methods more flexible or easier to call, e.g. <code>FnMut: FnOnce</code>, <code>Fn: FnMut</code></li>
<li>a subtrait might extend a supertrait and add new methods, e.g. <code>DoubleEndedIterator: Iterator</code>, <code>ExactSizeIterator: Iterator</code></li>
</ul>
<h3 id="trait-objects"><a class="header" href="#trait-objects">Trait Objects</a></h3>
<p>Generics give us compile-time polymorphism where trait objects give us run-time polymorphism. We can use trait objects to allow functions to dynamically return different types at run-time:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn example(condition: bool, vec: Vec&lt;i32&gt;) -&gt; Box&lt;dyn Iterator&lt;Item = i32&gt;&gt; {
    let iter = vec.into_iter();
    if condition {
        // Has type:
        // Box&lt;Map&lt;IntoIter&lt;i32&gt;, Fn(i32) -&gt; i32&gt;&gt;
        // But is cast to:
        // Box&lt;dyn Iterator&lt;Item = i32&gt;&gt;
        Box::new(iter.map(|n| n * 2))
    } else {
        // Has type:
        // Box&lt;Filter&lt;IntoIter&lt;i32&gt;, Fn(&amp;i32) -&gt; bool&gt;&gt;
        // But is cast to:
        // Box&lt;dyn Iterator&lt;Item = i32&gt;&gt;
        Box::new(iter.filter(|&amp;n| n &gt;= 2))
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>Trait objects also allow us to store heterogeneous types in collections:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::f64::consts::PI;

struct Circle {
    radius: f64,
}

struct Square {
    side: f64
}

trait Shape {
    fn area(&amp;self) -&gt; f64;
}

impl Shape for Circle {
    fn area(&amp;self) -&gt; f64 {
        PI * self.radius * self.radius
    }
}

impl Shape for Square {
    fn area(&amp;self) -&gt; f64 {
        self.side * self.side
    }
}

fn get_total_area(shapes: Vec&lt;Box&lt;dyn Shape&gt;&gt;) -&gt; f64 {
    shapes.into_iter().map(|s| s.area()).sum()
}

fn example() {
    let shapes: Vec&lt;Box&lt;dyn Shape&gt;&gt; = vec![
        Box::new(Circle { radius: 1.0 }), // Box&lt;Circle&gt; cast to Box&lt;dyn Shape&gt;
        Box::new(Square { side: 1.0 }), // Box&lt;Square&gt; cast to Box&lt;dyn Shape&gt;
    ];
    assert_eq!(PI + 1.0, get_total_area(shapes)); // ✅
}
<span class="boring">}
</span></code></pre></pre>
<p>Trait objects are unsized so they must always be behind a pointer. We can tell the difference between a concrete type and a trait object at the type level based on the presence of the <code>dyn</code> keyword within the type:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct Struct;
trait Trait {}

// regular struct
&amp;Struct
Box&lt;Struct&gt;
Rc&lt;Struct&gt;
Arc&lt;Struct&gt;

// trait objects
&amp;dyn Trait
Box&lt;dyn Trait&gt;
Rc&lt;dyn Trait&gt;
Arc&lt;dyn Trait&gt;
<span class="boring">}
</span></code></pre></pre>
<p>Not all traits can be converted into trait objects. A trait is object-safe if it meets these requirements:</p>
<ul>
<li>trait doesn't require <code>Self: Sized</code></li>
<li>all of the trait's methods are object-safe</li>
</ul>
<p>A trait method is object-safe if it meets these requirements:</p>
<ul>
<li>method requires <code>Self: Sized</code> or</li>
<li>method only uses a <code>Self</code> type in receiver position</li>
</ul>
<p>Understanding why the requirements are what they are is not relevant to the rest of this article, but if you're still curious it's covered in <a href="./sizedness-in-rust.html">Sizedness in Rust</a>.</p>
<h3 id="marker-traits"><a class="header" href="#marker-traits">Marker Traits</a></h3>
<p>Marker traits are traits that have no trait items. Their job is to &quot;mark&quot; the implementing type as having some property which is otherwise not possible to represent using the type system.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// Impling PartialEq for a type promises
// that equality for the type has these properties:
// - symmetry: a == b implies b == a, and
// - transitivity: a == b &amp;&amp; b == c implies a == c
// But DOES NOT promise this property:
// - reflexivity: a == a
trait PartialEq {
    fn eq(&amp;self, other: &amp;Self) -&gt; bool;
}

// Eq has no trait items! The eq method is already
// declared by PartialEq, but &quot;impling&quot; Eq
// for a type promises this additional equality property:
// - reflexivity: a == a
trait Eq: PartialEq {}

// f64 impls PartialEq but not Eq because NaN != NaN
// i32 impls PartialEq &amp; Eq because there's no NaNs :)
<span class="boring">}
</span></code></pre></pre>
<h3 id="auto-traits"><a class="header" href="#auto-traits">Auto Traits</a></h3>
<p>Auto traits are traits that get automatically implemented for a type if all of its members also impl the trait. What &quot;members&quot; means depends on the type, for example: fields of a struct, variants of an enum, elements of an array, items of a tuple, and so on.</p>
<p>All auto traits are marker traits but not all marker traits are auto traits. Auto traits must be marker traits so the compiler can provide an automatic default impl for them, which would not be possible if they had any trait items.</p>
<p>Examples of auto traits:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// implemented for types which are safe to send between threads
unsafe auto trait Send {}

// implemented for types whose references are safe to send between threads
unsafe auto trait Sync {}
<span class="boring">}
</span></code></pre></pre>
<h3 id="unsafe-traits"><a class="header" href="#unsafe-traits">Unsafe Traits</a></h3>
<p>Traits can be marked unsafe to indicate that impling the trait might require unsafe code. Both <code>Send</code> and <code>Sync</code> are marked <code>unsafe</code> because if they aren't automatically implemented for a type that means it must contains some non-<code>Send</code> or non-<code>Sync</code> member and we have to take extra care as the implementers to make sure there are no data races if we want to manually mark the type as <code>Send</code> and <code>Sync</code>.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// SomeType is not Send or Sync
struct SomeType {
    not_send_or_sync: *const (),
}

// but if we're confident that our impl doesn't have any data
// races we can explicitly mark it as Send and Sync using unsafe
unsafe impl Send for SomeType {}
unsafe impl Sync for SomeType {}
<span class="boring">}
</span></code></pre></pre>
<h2 id="auto-traits-1"><a class="header" href="#auto-traits-1">Auto Traits</a></h2>
<h3 id="send--sync"><a class="header" href="#send--sync">Send &amp; Sync</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#marker-traits">Marker Traits</a></li>
<li><a href="#auto-traits">Auto Traits</a></li>
<li><a href="#unsafe-traits">Unsafe Traits</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>unsafe auto trait Send {}
unsafe auto trait Sync {}
<span class="boring">}
</span></code></pre></pre>
<p>If a type is <code>Send</code> that means it's safe to send between threads. If a type is <code>Sync</code> that means it's safe to share references of it between threads. In more precise terms some type <code>T</code> is <code>Sync</code> if and only if <code>&amp;T</code> is <code>Send</code>.</p>
<p>Almost all types are <code>Send</code> and <code>Sync</code>. The only notable <code>Send</code> exception is <code>Rc</code> and the only notable <code>Sync</code> exceptions are <code>Rc</code>, <code>Cell</code>, <code>RefCell</code>. If we need a <code>Send</code> version of <code>Rc</code> we can use <code>Arc</code>. If we need a <code>Sync</code> version of <code>Cell</code> or <code>RefCell</code> we can <code>Mutex</code> or <code>RwLock</code>. Although if we're using the <code>Mutex</code> or <code>RwLock</code> to just wrap a primitive type it's often better to use the atomic primitive types provided by the standard library such as <code>AtomicBool</code>, <code>AtomicI32</code>, <code>AtomicUsize</code>, and so on.</p>
<p>That almost all types are <code>Sync</code> might be a surprise to some people, but yup, it's true even for types without any internal synchronization. This is possible thanks to Rust's strict borrowing rules.</p>
<p>We can pass many immutable references to the same data to many threads and we're guaranteed there are no data races because as long as any immutable references exist Rust statically guarantees the underlying data cannot be mutated:</p>
<pre><pre class="playground"><code class="language-rust">use crossbeam::thread;

fn main() {
    let mut greeting = String::from(&quot;Hello&quot;);
    let greeting_ref = &amp;greeting;
    
    thread::scope(|scoped_thread| {
        // spawn 3 threads
        for n in 1..=3 {
            // greeting_ref copied into every thread
            scoped_thread.spawn(move |_| {
                println!(&quot;{} {}&quot;, greeting_ref, n); // prints &quot;Hello {n}&quot;
            });
        }
        
        // line below could cause UB or data races but compiler rejects it
        greeting += &quot; world&quot;; // ❌ cannot mutate greeting while immutable refs exist
    });
    
    // can mutate greeting after every thread has joined
    greeting += &quot; world&quot;; // ✅
    println!(&quot;{}&quot;, greeting); // prints &quot;Hello world&quot;
}
</code></pre></pre>
<p>Likewise we can pass a single mutable reference to some data to a single thread and we're guaranteed there will be no data races because Rust statically guarantees aliased mutable references cannot exist and the underlying data cannot be mutated through anything other than the single existing mutable reference:</p>
<pre><pre class="playground"><code class="language-rust">use crossbeam::thread;

fn main() {
    let mut greeting = String::from(&quot;Hello&quot;);
    let greeting_ref = &amp;mut greeting;
    
    thread::scope(|scoped_thread| {
        // greeting_ref moved into thread
        scoped_thread.spawn(move |_| {
            *greeting_ref += &quot; world&quot;;
            println!(&quot;{}&quot;, greeting_ref); // prints &quot;Hello world&quot;
        });
        
        // line below could cause UB or data races but compiler rejects it
        greeting += &quot;!!!&quot;; // ❌ cannot mutate greeting while mutable refs exist
    });
    
    // can mutate greeting after the thread has joined
    greeting += &quot;!!!&quot;; // ✅
    println!(&quot;{}&quot;, greeting); // prints &quot;Hello world!!!&quot;
}
</code></pre></pre>
<p>This is why most types are <code>Sync</code> without requiring any explicit synchronization. In the event we need to simultaneously mutate some data <code>T</code> across multiple threads the compiler won't let us until we wrap the data in a <code>Arc&lt;Mutex&lt;T&gt;&gt;</code> or <code>Arc&lt;RwLock&lt;T&gt;&gt;</code> so the compiler enforces that explicit synchronization is used when it's needed.</p>
<h3 id="sized"><a class="header" href="#sized">Sized</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#marker-traits">Marker Traits</a></li>
<li><a href="#auto-traits">Auto Traits</a></li>
</ul>
<p>If a type is <code>Sized</code> that means its size in bytes is known at compile-time and it's possible to put instances of the type on the stack.</p>
<p>Sizedness of types and its implications is a subtle yet huge topic that affects a lot of different aspects of the language. It's so important that I wrote an entire article on it called <a href="./sizedness-in-rust.html">Sizedness in Rust</a> which I highly recommend reading for anyone who would like to understand sizedness in-depth. I'll summarize a few key things which are relevant to this article.</p>
<ol>
<li>All generic types get an implicit <code>Sized</code> bound.</li>
</ol>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn func&lt;T&gt;(t: &amp;T) {}

// example above desugared
fn func&lt;T: Sized&gt;(t: &amp;T) {}
<span class="boring">}
</span></code></pre></pre>
<ol start="2">
<li>Since there's an implicit <code>Sized</code> bound on all generic types, if we want to opt-out of this implicit bound we need to use the special <em>&quot;relaxed bound&quot;</em> syntax <code>?Sized</code> which currently only exists for the <code>Sized</code> trait:</li>
</ol>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// now T can be unsized
fn func&lt;T: ?Sized&gt;(t: &amp;T) {}
<span class="boring">}
</span></code></pre></pre>
<ol start="3">
<li>There's an implicit <code>?Sized</code> bound on all traits.</li>
</ol>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Trait {}

// example above desugared
trait Trait: ?Sized {}
<span class="boring">}
</span></code></pre></pre>
<p>This is so that trait objects can impl the trait. Again, all of the nitty gritty details are in <a href="./sizedness-in-rust.html">Sizedness in Rust</a>.</p>
<h2 id="general-traits"><a class="header" href="#general-traits">General traits</a></h2>
<h3 id="default"><a class="header" href="#default">Default</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#functions">Functions</a></li>
<li><a href="#derive-macros">Derive Macros</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Default {
    fn default() -&gt; Self;
}
<span class="boring">}
</span></code></pre></pre>
<p>It's possible to construct default values of <code>Default</code> types.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct Color {
    r: u8,
    g: u8,
    b: u8,
}

impl Default for Color {
    // default color is black
    fn default() -&gt; Self {
        Color {
            r: 0,
            g: 0,
            b: 0,
        }
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>This is useful for quick prototyping but also in any instance where we just need an instance of a type and aren't picky about what it is:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    // just give me some color!
    let color = Color::default();
}
</code></pre></pre>
<p>This is also an option we may want to explicitly expose to the users of our functions:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct Canvas;
enum Shape {
    Circle,
    Rectangle,
}

impl Canvas {
    // let user optionally pass a color
    fn paint(&amp;mut self, shape: Shape, color: Option&lt;Color&gt;) {
        // if no color is passed use the default color
        let color = color.unwrap_or_default();
        // etc
    }
}
<span class="boring">}
</span></code></pre></pre>
<p><code>Default</code> is also useful in generic contexts where we need to construct generic types:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn guarantee_length&lt;T: Default&gt;(mut vec: Vec&lt;T&gt;, min_len: usize) -&gt; Vec&lt;T&gt; {
    for _ in 0..min_len.saturating_sub(vec.len()) {
        vec.push(T::default());
    }
    vec
}
<span class="boring">}
</span></code></pre></pre>
<p>Another way we can take advantage of <code>Default</code> types is for partial initialization of structs using Rust's struct update syntax. We may have a <code>new</code> constructor for <code>Color</code> which takes every member as an argument:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>impl Color {
    fn new(r: u8, g: u8, b: u8) -&gt; Self {
        Color {
            r,
            g,
            b,
        }
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>However we can also have convenience constructors that only accept a particular struct member each and fall back to the default values for the other struct members:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>impl Color {
    fn red(r: u8) -&gt; Self {
        Color {
            r,
            ..Color::default()
        }
    }
    fn green(g: u8) -&gt; Self {
        Color {
            g,
            ..Color::default()
        }
    }
    fn blue(b: u8) -&gt; Self {
        Color {
            b,
            ..Color::default()
        }
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>There's also a <code>Default</code> derive macro for so we can write <code>Color</code> like this:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// default color is still black
// because u8::default() == 0
#[derive(Default)]
struct Color {
    r: u8,
    g: u8,
    b: u8
}
<span class="boring">}
</span></code></pre></pre>
<h3 id="clone"><a class="header" href="#clone">Clone</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#default-impls">Default Impls</a></li>
<li><a href="#derive-macros">Derive Macros</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Clone {
    fn clone(&amp;self) -&gt; Self;

    // provided default impls
    fn clone_from(&amp;mut self, source: &amp;Self);
}
<span class="boring">}
</span></code></pre></pre>
<p>We can convert immutable references of <code>Clone</code> types into owned values, i.e. <code>&amp;T</code> -&gt; <code>T</code>. <code>Clone</code> makes no promises about the efficiency of this conversion so it can be slow and expensive. To quickly impl <code>Clone</code> on a type we can use the derive macro:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>#[derive(Clone)]
struct SomeType {
    cloneable_member1: CloneableType1,
    cloneable_member2: CloneableType2,
    // etc
}

// macro generates impl below
impl Clone for SomeType {
    fn clone(&amp;self) -&gt; Self {
        SomeType {
            cloneable_member1: self.cloneable_member1.clone(),
            cloneable_member2: self.cloneable_member2.clone(),
            // etc
        }
    }
}
<span class="boring">}
</span></code></pre></pre>
<p><code>Clone</code> can also be useful in constructing instances of a type within a generic context. Here's a modified example from the previous section except using <code>Clone</code> instead of <code>Default</code>:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn guarantee_length&lt;T: Clone&gt;(mut vec: Vec&lt;T&gt;, min_len: usize, fill_with: &amp;T) -&gt; Vec&lt;T&gt; {
    for _ in 0..min_len.saturating_sub(vec.len()) {
        vec.push(fill_with.clone());
    }
    vec
}
<span class="boring">}
</span></code></pre></pre>
<p>People also commonly use cloning as an escape hatch to avoid dealing with the borrow checker. Managing structs with references can be challenging, but we can turn the references into owned values by cloning them.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// oof, we gotta worry about lifetimes 😟
struct SomeStruct&lt;'a&gt; {
    data: &amp;'a Vec&lt;u8&gt;,
}

// now we're on easy street 😎
struct SomeStruct {
    data: Vec&lt;u8&gt;,
}
<span class="boring">}
</span></code></pre></pre>
<p>If we're working on a program where performance is not the utmost concern then we don't need to sweat cloning data. Rust is a low-level language that exposes a lot of low-level details so it's easy to get caught up in premature optimizations instead of actually solving the problem at hand. For many programs the best order of priorities is usually to build for correctness first, elegance second, and performance third, and only focus on performance after the program has been profiled and the performance bottlenecks have been identified. This is good general advice to follow, and if it doesn't apply to your particular program then you would know.</p>
<h3 id="copy"><a class="header" href="#copy">Copy</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#marker-traits">Marker Traits</a></li>
<li><a href="#subtraits--supertraits">Subtraits &amp; Supertraits</a></li>
<li><a href="#derive-macros">Derive Macros</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Copy: Clone {}
<span class="boring">}
</span></code></pre></pre>
<p>We copy <code>Copy</code> types, e.g. <code>T</code> -&gt; <code>T</code>. <code>Copy</code> promises the copy operation will be a simple bitwise copy so it will be very fast and efficient. We cannot impl <code>Copy</code> ourselves, only the compiler can provide an impl, but we can tell it to do so by using the <code>Copy</code> derive macro, together with the <code>Clone</code> derive macro since <code>Copy</code> is a subtrait of <code>Clone</code>:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>#[derive(Copy, Clone)]
struct SomeType;
<span class="boring">}
</span></code></pre></pre>
<p><code>Copy</code> refines <code>Clone</code>. A clone may be slow and expensive but a copy is guaranteed to be fast and cheap, so a copy is just a fast clone. If a type impls <code>Copy</code> that makes the <code>Clone</code> impl trivial:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// this is what the derive macro generates
impl&lt;T: Copy&gt; Clone for T {
    // the clone method becomes just a copy
    fn clone(&amp;self) -&gt; Self {
        *self
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>Impling <code>Copy</code> for a type changes its behavior when it gets moved. By default all types have <em>move semantics</em> but once a type impls <code>Copy</code> it gets <em>copy semantics</em>. To explain the difference between the two let's examine these simple scenarios:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// a &quot;move&quot;, src: !Copy
let dest = src; 

// a &quot;copy&quot;, src: Copy
let dest = src;
<span class="boring">}
</span></code></pre></pre>
<p>In both cases, <code>dest = src</code> performs a simple bitwise copy of <code>src</code>'s contents and moves the result into <code>dest</code>, the only difference is that in the case of <em>&quot;a move&quot;</em> the borrow checker invalidates the <code>src</code> variable and makes sure it's not used anywhere else later and in the case of <em>&quot;a copy&quot;</em> <code>src</code> remains valid and usable.</p>
<p>In a nutshell: Copies <em>are</em> moves. Moves <em>are</em> copies. The only difference is how they're treated by the borrow checker.</p>
<p>For a more concrete example of a move, imagine <code>src</code> was a <code>Vec&lt;i32&gt;</code> and its contents looked something like this:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>{ data: *mut [i32], length: usize, capacity: usize }
<span class="boring">}
</span></code></pre></pre>
<p>When we write <code>dest = src</code> we end up with:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>src = { data: *mut [i32], length: usize, capacity: usize }
dest = { data: *mut [i32], length: usize, capacity: usize }
<span class="boring">}
</span></code></pre></pre>
<p>At this point both <code>src</code> and <code>dest</code> have aliased mutable references to the same data, which is a big no-no, so the borrow checker invalidates the <code>src</code> variable so it can't be used again without throwing a compile error.</p>
<p>For a more concrete example of a copy, imagine <code>src</code> was an <code>Option&lt;i32&gt;</code> and its contents looked something like this:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>{ is_valid: bool, data: i32 }
<span class="boring">}
</span></code></pre></pre>
<p>Now when we write <code>dest = src</code> we end up with:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>src = { is_valid: bool, data: i32 }
dest = { is_valid: bool, data: i32 }
<span class="boring">}
</span></code></pre></pre>
<p>These are both usable simultaneously! Hence <code>Option&lt;i32&gt;</code> is <code>Copy</code>.</p>
<p>Although <code>Copy</code> could be an auto trait the Rust language designers decided it's simpler and safer for types to explicitly opt into copy semantics rather than silently inheriting copy semantics whenever the type is eligible, as the latter can cause surprising confusing behavior which often leads to bugs.</p>
<h3 id="any"><a class="header" href="#any">Any</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#generic-blanket-impls">Generic Blanket Impls</a></li>
<li><a href="#subtraits--supertraits">Subtraits &amp; Supertraits</a></li>
<li><a href="#trait-objects">Trait Objects</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Any: 'static {
    fn type_id(&amp;self) -&gt; TypeId;
}
<span class="boring">}
</span></code></pre></pre>
<p>Rust's style of polymorphism is parametric, but if we're looking to use a more ad-hoc style of polymorphism similar to dynamically-typed languages then we can emulate that using the <code>Any</code> trait. We don't have to manually impl this trait for our types because that's already covered by this generic blanket impl:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>impl&lt;T: 'static + ?Sized&gt; Any for T {
    fn type_id(&amp;self) -&gt; TypeId {
        TypeId::of::&lt;T&gt;()
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>The way we get a <code>T</code> out of a <code>dyn Any</code> is by using the <code>downcast_ref::&lt;T&gt;()</code> and <code>downcast_mut::&lt;T&gt;()</code> methods:</p>
<pre><pre class="playground"><code class="language-rust">use std::any::Any;

#[derive(Default)]
struct Point {
    x: i32,
    y: i32,
}

impl Point {
    fn inc(&amp;mut self) {
        self.x += 1;
        self.y += 1;
    }
}

fn map_any(mut any: Box&lt;dyn Any&gt;) -&gt; Box&lt;dyn Any&gt; {
    if let Some(num) = any.downcast_mut::&lt;i32&gt;() {
        *num += 1;
    } else if let Some(string) = any.downcast_mut::&lt;String&gt;() {
        *string += &quot;!&quot;;
    } else if let Some(point) = any.downcast_mut::&lt;Point&gt;() {
        point.inc();
    }
    any
}

fn main() {
    let mut vec: Vec&lt;Box&lt;dyn Any&gt;&gt; = vec![
        Box::new(0),
        Box::new(String::from(&quot;a&quot;)),
        Box::new(Point::default()),
    ];
    // vec = [0, &quot;a&quot;, Point { x: 0, y: 0 }]
    vec = vec.into_iter().map(map_any).collect();
    // vec = [1, &quot;a!&quot;, Point { x: 1, y: 1 }]
}
</code></pre></pre>
<p>This trait rarely <em>needs</em> to be used because on top of parametric polymorphism being superior to ad-hoc polymorphism in most scenarios the latter can also be emulated using enums which are more type-safe and require less indirection. For example, we could have written the above example like this:</p>
<pre><pre class="playground"><code class="language-rust">#[derive(Default)]
struct Point {
    x: i32,
    y: i32,
}

impl Point {
    fn inc(&amp;mut self) {
        self.x += 1;
        self.y += 1;
    }
}

enum Stuff {
    Integer(i32),
    String(String),
    Point(Point),
}

fn map_stuff(mut stuff: Stuff) -&gt; Stuff {
    match &amp;mut stuff {
        Stuff::Integer(num) =&gt; *num += 1,
        Stuff::String(string) =&gt; *string += &quot;!&quot;,
        Stuff::Point(point) =&gt; point.inc(),
    }
    stuff
}

fn main() {
    let mut vec = vec![
        Stuff::Integer(0),
        Stuff::String(String::from(&quot;a&quot;)),
        Stuff::Point(Point::default()),
    ];
    // vec = [0, &quot;a&quot;, Point { x: 0, y: 0 }]
    vec = vec.into_iter().map(map_stuff).collect();
    // vec = [1, &quot;a!&quot;, Point { x: 1, y: 1 }]
}
</code></pre></pre>
<p>Despite <code>Any</code> rarely being <em>needed</em> it can still be convenient to use sometimes, as we'll later see in the <strong>Error Handling</strong> section.</p>
<h2 id="formatting-traits"><a class="header" href="#formatting-traits">Formatting Traits</a></h2>
<p>We can serialize types into strings using the formatting macros in <code>std::fmt</code>, the most well-known of the bunch being <code>println!</code>. We can pass formatting parameters to the <code>{}</code> placeholders used within format <code>str</code>s which are then used to select which trait impl to use to serialize the placeholder's argument.</p>
<div class="table-wrapper"><table><thead><tr><th>Trait</th><th>Placeholder</th><th>Description</th></tr></thead><tbody>
<tr><td><code>Display</code></td><td><code>{}</code></td><td>display representation</td></tr>
<tr><td><code>Debug</code></td><td><code>{:?}</code></td><td>debug representation</td></tr>
<tr><td><code>Octal</code></td><td><code>{:o}</code></td><td>octal representation</td></tr>
<tr><td><code>LowerHex</code></td><td><code>{:x}</code></td><td>lowercase hex representation</td></tr>
<tr><td><code>UpperHex</code></td><td><code>{:X}</code></td><td>uppercase hex representation</td></tr>
<tr><td><code>Pointer</code></td><td><code>{:p}</code></td><td>memory address</td></tr>
<tr><td><code>Binary</code></td><td><code>{:b}</code></td><td>binary representation</td></tr>
<tr><td><code>LowerExp</code></td><td><code>{:e}</code></td><td>lowercase exponential representation</td></tr>
<tr><td><code>UpperExp</code></td><td><code>{:E}</code></td><td>uppercase exponential representation</td></tr>
</tbody></table>
</div>
<h3 id="display--tostring"><a class="header" href="#display--tostring">Display &amp; ToString</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#generic-blanket-impls">Generic Blanket Impls</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Display {
    fn fmt(&amp;self, f: &amp;mut Formatter&lt;'_&gt;) -&gt; Result;
}
<span class="boring">}
</span></code></pre></pre>
<p><code>Display</code> types can be serialized into <code>String</code>s which are friendly to the end users of the program. Example impl for <code>Point</code>:</p>
<pre><pre class="playground"><code class="language-rust">use std::fmt;

#[derive(Default)]
struct Point {
    x: i32,
    y: i32,
}

impl fmt::Display for Point {
    fn fmt(&amp;self, f: &amp;mut fmt::Formatter&lt;'_&gt;) -&gt; fmt::Result {
        write!(f, &quot;({}, {})&quot;, self.x, self.y)
    }
}

fn main() {
    println!(&quot;origin: {}&quot;, Point::default());
    // prints &quot;origin: (0, 0)&quot;

    // get Point's Display representation as a String
    let stringified_point = format!(&quot;{}&quot;, Point::default());
    assert_eq!(&quot;(0, 0)&quot;, stringified_point); // ✅
}
</code></pre></pre>
<p>Aside from using the <code>format!</code> macro to get a type's display representation as a <code>String</code> we can use the <code>ToString</code> trait:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait ToString {
    fn to_string(&amp;self) -&gt; String;
}
<span class="boring">}
</span></code></pre></pre>
<p>There's no need for us to impl this ourselves. In fact we can't, because of this generic blanket impl that automatically impls <code>ToString</code> for any type which impls <code>Display</code>:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>impl&lt;T: Display + ?Sized&gt; ToString for T;
<span class="boring">}
</span></code></pre></pre>
<p>Using <code>ToString</code> with <code>Point</code>:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>#[test] // ✅
fn display_point() {
    let origin = Point::default();
    assert_eq!(format!(&quot;{}&quot;, origin), &quot;(0, 0)&quot;);
}

#[test] // ✅
fn point_to_string() {
    let origin = Point::default();
    assert_eq!(origin.to_string(), &quot;(0, 0)&quot;);
}

#[test] // ✅
fn display_equals_to_string() {
    let origin = Point::default();
    assert_eq!(format!(&quot;{}&quot;, origin), origin.to_string());
}
<span class="boring">}
</span></code></pre></pre>
<h3 id="debug"><a class="header" href="#debug">Debug</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#derive-macros">Derive Macros</a></li>
<li><a href="#display--tostring">Display &amp; ToString</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Debug {
    fn fmt(&amp;self, f: &amp;mut Formatter&lt;'_&gt;) -&gt; Result;
}
<span class="boring">}
</span></code></pre></pre>
<p><code>Debug</code> has an identical signature to <code>Display</code>. The only difference is that the <code>Debug</code> impl is called when we use the <code>{:?}</code> formatting specifier. <code>Debug</code> can be derived:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::fmt;

#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}

// derive macro generates impl below
impl fmt::Debug for Point {
    fn fmt(&amp;self, f: &amp;mut fmt::Formatter&lt;'_&gt;) -&gt; fmt::Result {
        f.debug_struct(&quot;Point&quot;)
            .field(&quot;x&quot;, &amp;self.x)
            .field(&quot;y&quot;, &amp;self.y)
            .finish()
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>Impling <code>Debug</code> for a type also allows it to be used within the <code>dbg!</code> macro which is superior to <code>println!</code> for quick and dirty print logging. Some of its advantages:</p>
<ol>
<li><code>dbg!</code> prints to stderr instead of stdout so the debug logs are easy to separate from the actual stdout output of our program.</li>
<li><code>dbg!</code> prints the expression passed to it as well as the value the expression evaluated to.</li>
<li><code>dbg!</code> takes ownership of its arguments and returns them so you can use it within expressions:</li>
</ol>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn some_condition() -&gt; bool {
    true
}

// no logging
fn example() {
    if some_condition() {
        // some code
    }
}

// println! logging
fn example_println() {
    // 🤦
    let result = some_condition();
    println!(&quot;{}&quot;, result); // just prints &quot;true&quot;
    if result {
        // some code
    }
}

// dbg! logging
fn example_dbg() {
    // 😍
    if dbg!(some_condition()) { // prints &quot;[src/main.rs:22] some_condition() = true&quot;
        // some code
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>The only downside is that <code>dbg!</code> isn't automatically stripped in release builds so we have to manually remove it from our code if we don't want to ship it in the final executable.</p>
<h2 id="operator-traits"><a class="header" href="#operator-traits">Operator Traits</a></h2>
<p>All operators in Rust are associated with traits. If we'd like to impl operators for our types we have to impl the associated traits.</p>
<div class="table-wrapper"><table><thead><tr><th>Trait(s)</th><th>Category</th><th>Operator(s)</th><th>Description</th></tr></thead><tbody>
<tr><td><code>Eq</code>, <code>PartialEq</code></td><td>comparison</td><td><code>==</code></td><td>equality</td></tr>
<tr><td><code>Ord</code>, <code>PartialOrd</code></td><td>comparison</td><td><code>&lt;</code>, <code>&gt;</code>, <code>&lt;=</code>, <code>&gt;=</code></td><td>comparison</td></tr>
<tr><td><code>Add</code></td><td>arithmetic</td><td><code>+</code></td><td>addition</td></tr>
<tr><td><code>AddAssign</code></td><td>arithmetic</td><td><code>+=</code></td><td>addition assignment</td></tr>
<tr><td><code>BitAnd</code></td><td>arithmetic</td><td><code>&amp;</code></td><td>bitwise AND</td></tr>
<tr><td><code>BitAndAssign</code></td><td>arithmetic</td><td><code>&amp;=</code></td><td>bitwise assignment</td></tr>
<tr><td><code>BitXor</code></td><td>arithmetic</td><td><code>^</code></td><td>bitwise XOR</td></tr>
<tr><td><code>BitXorAssign</code></td><td>arithmetic</td><td><code>^=</code></td><td>bitwise XOR assignment</td></tr>
<tr><td><code>Div</code></td><td>arithmetic</td><td><code>/</code></td><td>division</td></tr>
<tr><td><code>DivAssign</code></td><td>arithmetic</td><td><code>/=</code></td><td>division assignment</td></tr>
<tr><td><code>Mul</code></td><td>arithmetic</td><td><code>*</code></td><td>multiplication</td></tr>
<tr><td><code>MulAssign</code></td><td>arithmetic</td><td><code>*=</code></td><td>multiplication assignment</td></tr>
<tr><td><code>Neg</code></td><td>arithmetic</td><td><code>-</code></td><td>unary negation</td></tr>
<tr><td><code>Not</code></td><td>arithmetic</td><td><code>!</code></td><td>unary logical negation</td></tr>
<tr><td><code>Rem</code></td><td>arithmetic</td><td><code>%</code></td><td>remainder</td></tr>
<tr><td><code>RemAssign</code></td><td>arithmetic</td><td><code>%=</code></td><td>remainder assignment</td></tr>
<tr><td><code>Shl</code></td><td>arithmetic</td><td><code>&lt;&lt;</code></td><td>left shift</td></tr>
<tr><td><code>ShlAssign</code></td><td>arithmetic</td><td><code>&lt;&lt;=</code></td><td>left shift assignment</td></tr>
<tr><td><code>Shr</code></td><td>arithmetic</td><td><code>&gt;&gt;</code></td><td>right shift</td></tr>
<tr><td><code>ShrAssign</code></td><td>arithmetic</td><td><code>&gt;&gt;=</code></td><td>right shift assignment</td></tr>
<tr><td><code>Sub</code></td><td>arithmetic</td><td><code>-</code></td><td>subtraction</td></tr>
<tr><td><code>SubAssign</code></td><td>arithmetic</td><td><code>-=</code></td><td>subtraction assignment</td></tr>
<tr><td><code>Fn</code></td><td>closure</td><td><code>(...args)</code></td><td>immutable closure invocation</td></tr>
<tr><td><code>FnMut</code></td><td>closure</td><td><code>(...args)</code></td><td>mutable closure invocation</td></tr>
<tr><td><code>FnOnce</code></td><td>closure</td><td><code>(...args)</code></td><td>one-time closure invocation</td></tr>
<tr><td><code>Deref</code></td><td>other</td><td><code>*</code></td><td>immutable dereference</td></tr>
<tr><td><code>DerefMut</code></td><td>other</td><td><code>*</code></td><td>mutable dereference</td></tr>
<tr><td><code>Drop</code></td><td>other</td><td>-</td><td>type destructor</td></tr>
<tr><td><code>Index</code></td><td>other</td><td><code>[]</code></td><td>immutable index</td></tr>
<tr><td><code>IndexMut</code></td><td>other</td><td><code>[]</code></td><td>mutable index</td></tr>
<tr><td><code>RangeBounds</code></td><td>other</td><td><code>..</code></td><td>range</td></tr>
</tbody></table>
</div>
<h3 id="comparison-traits"><a class="header" href="#comparison-traits">Comparison Traits</a></h3>
<div class="table-wrapper"><table><thead><tr><th>Trait(s)</th><th>Category</th><th>Operator(s)</th><th>Description</th></tr></thead><tbody>
<tr><td><code>Eq</code>, <code>PartialEq</code></td><td>comparison</td><td><code>==</code></td><td>equality</td></tr>
<tr><td><code>Ord</code>, <code>PartialOrd</code></td><td>comparison</td><td><code>&lt;</code>, <code>&gt;</code>, <code>&lt;=</code>, <code>&gt;=</code></td><td>comparison</td></tr>
</tbody></table>
</div>
<h4 id="partialeq--eq"><a class="header" href="#partialeq--eq">PartialEq &amp; Eq</a></h4>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#generic-parameters">Generic Parameters</a></li>
<li><a href="#default-impls">Default Impls</a></li>
<li><a href="#generic-blanket-impls">Generic Blanket Impls</a></li>
<li><a href="#marker-traits">Marker Traits</a></li>
<li><a href="#subtraits--supertraits">Subtraits &amp; Supertraits</a></li>
<li><a href="#sized">Sized</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait PartialEq&lt;Rhs = Self&gt; 
where
    Rhs: ?Sized, 
{
    fn eq(&amp;self, other: &amp;Rhs) -&gt; bool;

    // provided default impls
    fn ne(&amp;self, other: &amp;Rhs) -&gt; bool;
}
<span class="boring">}
</span></code></pre></pre>
<p><code>PartialEq&lt;Rhs&gt;</code> types can be checked for equality to <code>Rhs</code> types using the <code>==</code> operator.</p>
<p>All <code>PartialEq&lt;Rhs&gt;</code> impls must ensure that equality is symmetric and transitive. That means for all <code>a</code>, <code>b</code>, and <code>c</code>:</p>
<ul>
<li><code>a == b</code> implies <code>b == a</code> (symmetry)</li>
<li><code>a == b &amp;&amp; b == c</code> implies <code>a == c</code> (transitivity) </li>
</ul>
<p>By default <code>Rhs = Self</code> because we almost always want to compare instances of a type to each other, and not to instances of different types. This also automatically guarantees our impl is symmetric and transitive.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct Point {
    x: i32,
    y: i32
}

// Rhs == Self == Point
impl PartialEq for Point {
    // impl automatically symmetric &amp; transitive
    fn eq(&amp;self, other: &amp;Point) -&gt; bool {
        self.x == other.x &amp;&amp; self.y == other.y
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>If all the members of a type impl <code>PartialEq</code> then it can be derived:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>#[derive(PartialEq)]
struct Point {
    x: i32,
    y: i32
}

#[derive(PartialEq)]
enum Suit {
    Spade,
    Heart,
    Club,
    Diamond,
}
<span class="boring">}
</span></code></pre></pre>
<p>Once we impl <code>PartialEq</code> for our type we also get equality comparisons between references of our type for free thanks to these generic blanket impls:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// this impl only gives us: Point == Point
#[derive(PartialEq)]
struct Point {
    x: i32,
    y: i32
}

// all of the generic blanket impls below
// are provided by the standard library

// this impl gives us: &amp;Point == &amp;Point
impl&lt;A, B&gt; PartialEq&lt;&amp;'_ B&gt; for &amp;'_ A
where A: PartialEq&lt;B&gt; + ?Sized, B: ?Sized;

// this impl gives us: &amp;mut Point == &amp;Point
impl&lt;A, B&gt; PartialEq&lt;&amp;'_ B&gt; for &amp;'_ mut A
where A: PartialEq&lt;B&gt; + ?Sized, B: ?Sized;

// this impl gives us: &amp;Point == &amp;mut Point
impl&lt;A, B&gt; PartialEq&lt;&amp;'_ mut B&gt; for &amp;'_ A
where A: PartialEq&lt;B&gt; + ?Sized, B: ?Sized;

// this impl gives us: &amp;mut Point == &amp;mut Point
impl&lt;A, B&gt; PartialEq&lt;&amp;'_ mut B&gt; for &amp;'_ mut A
where A: PartialEq&lt;B&gt; + ?Sized, B: ?Sized;
<span class="boring">}
</span></code></pre></pre>
<p>Since this trait is generic we can define equality between different types. The standard library leverages this to allow checking equality between the many string-like types such as <code>String</code>, <code>&amp;str</code>, <code>PathBuf</code>, <code>&amp;Path</code>, <code>OsString</code>, <code>&amp;OsStr</code>, and so on.</p>
<p>Generally, we should only impl equality between different types <em>if they contain the same kind of data</em> and the only difference between the types is how they represent the data or how they allow interacting with the data.</p>
<p>Here's a cute but bad example of how someone might be tempted to impl <code>PartialEq</code> to check equality between different types that don't meet the above criteria:</p>
<pre><pre class="playground"><code class="language-rust">#[derive(PartialEq)]
enum Suit {
    Spade,
    Club,
    Heart,
    Diamond,
}

#[derive(PartialEq)]
enum Rank {
    Ace,
    Two,
    Three,
    Four,
    Five,
    Six,
    Seven,
    Eight,
    Nine,
    Ten,
    Jack,
    Queen,
    King,
}

#[derive(PartialEq)]
struct Card {
    suit: Suit,
    rank: Rank,
}

// check equality of Card's suit
impl PartialEq&lt;Suit&gt; for Card {
    fn eq(&amp;self, other: &amp;Suit) -&gt; bool {
        self.suit == *other
    }
}

// check equality of Card's rank
impl PartialEq&lt;Rank&gt; for Card {
    fn eq(&amp;self, other: &amp;Rank) -&gt; bool {
        self.rank == *other
    }
}

fn main() {
    let AceOfSpades = Card {
        suit: Suit::Spade,
        rank: Rank::Ace,
    };
    assert!(AceOfSpades == Suit::Spade); // ✅
    assert!(AceOfSpades == Rank::Ace); // ✅
}
</code></pre></pre>
<p>It works and kinda makes sense. A card which is an Ace of Spades is both an Ace and a Spade, and if we're writing a library to handle playing cards it's reasonable that we'd want to make it easy and convenient to individually check the suit and rank of a card. However, something's missing: symmetry! We can <code>Card == Suit</code> and <code>Card == Rank</code> but we cannot <code>Suit == Card</code> or <code>Rank == Card</code> so let's fix that:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// check equality of Card's suit
impl PartialEq&lt;Suit&gt; for Card {
    fn eq(&amp;self, other: &amp;Suit) -&gt; bool {
        self.suit == *other
    }
}

// added for symmetry
impl PartialEq&lt;Card&gt; for Suit {
    fn eq(&amp;self, other: &amp;Card) -&gt; bool {
        *self == other.suit
    }
}

// check equality of Card's rank
impl PartialEq&lt;Rank&gt; for Card {
    fn eq(&amp;self, other: &amp;Rank) -&gt; bool {
        self.rank == *other
    }
}

// added for symmetry
impl PartialEq&lt;Card&gt; for Rank {
    fn eq(&amp;self, other: &amp;Card) -&gt; bool {
        *self == other.rank
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>We have symmetry! Great. Adding symmetry just broke transitivity! Oops. This is now possible:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    // Ace of Spades
    let a = Card {
        suit: Suit::Spade,
        rank: Rank::Ace,
    };
    let b = Suit::Spade;
    // King of Spades
    let c = Card {
        suit: Suit::Spade,
        rank: Rank::King,
    };
    assert!(a == b &amp;&amp; b == c); // ✅
    assert!(a == c); // ❌
}
</code></pre></pre>
<p>A good example of impling <code>PartialEq</code> to check equality between different types would be a program that works with distances and uses different types to represent different units of measurement.</p>
<pre><pre class="playground"><code class="language-rust">#[derive(PartialEq)]
struct Foot(u32);

#[derive(PartialEq)]
struct Yard(u32);

#[derive(PartialEq)]
struct Mile(u32);

impl PartialEq&lt;Mile&gt; for Foot {
    fn eq(&amp;self, other: &amp;Mile) -&gt; bool {
        self.0 == other.0 * 5280
    }
}

impl PartialEq&lt;Foot&gt; for Mile {
    fn eq(&amp;self, other: &amp;Foot) -&gt; bool {
        self.0 * 5280 == other.0
    }    
}

impl PartialEq&lt;Mile&gt; for Yard {
    fn eq(&amp;self, other: &amp;Mile) -&gt; bool {
        self.0 == other.0 * 1760
    }
}

impl PartialEq&lt;Yard&gt; for Mile {
    fn eq(&amp;self, other: &amp;Yard) -&gt; bool {
        self.0 * 1760 == other.0
    }    
}

impl PartialEq&lt;Foot&gt; for Yard {
    fn eq(&amp;self, other: &amp;Foot) -&gt; bool {
        self.0 * 3 == other.0
    }
}

impl PartialEq&lt;Yard&gt; for Foot {
    fn eq(&amp;self, other: &amp;Yard) -&gt; bool {
        self.0 == other.0 * 3
    }
}

fn main() {
    let a = Foot(5280);
    let b = Yard(1760);
    let c = Mile(1);
    
    // symmetry
    assert!(a == b &amp;&amp; b == a); // ✅
    assert!(b == c &amp;&amp; c == b); // ✅
    assert!(a == c &amp;&amp; c == a); // ✅

    // transitivity
    assert!(a == b &amp;&amp; b == c &amp;&amp; a == c); // ✅
    assert!(c == b &amp;&amp; b == a &amp;&amp; c == a); // ✅
}
</code></pre></pre>
<p><code>Eq</code> is a marker trait and a subtrait of <code>PartialEq&lt;Self&gt;</code>.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Eq: PartialEq&lt;Self&gt; {}
<span class="boring">}
</span></code></pre></pre>
<p>If we impl <code>Eq</code> for a type, on top of the symmetry &amp; transitivity properties required by <code>PartialEq</code>, we're also guaranteeing reflexivity, i.e. <code>a == a</code> for all <code>a</code>. In this sense <code>Eq</code> refines <code>PartialEq</code> because it represents a stricter version of equality. If all members of a type impl <code>Eq</code> then the <code>Eq</code> impl can be derived for the type.</p>
<p>Floats are <code>PartialEq</code> but not <code>Eq</code> because <code>NaN != NaN</code>. Almost all other <code>PartialEq</code> types are trivially <code>Eq</code>, unless of course if they contain floats.</p>
<p>Once a type impls <code>PartialEq</code> and <code>Debug</code> we can use it in the <code>assert_eq!</code> macro. We can also compare collections of <code>PartialEq</code> types.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>#[derive(PartialEq, Debug)]
struct Point {
    x: i32,
    y: i32,
}

fn example_assert(p1: Point, p2: Point) {
    assert_eq!(p1, p2);
}

fn example_compare_collections&lt;T: PartialEq&gt;(vec1: Vec&lt;T&gt;, vec2: Vec&lt;T&gt;) {
    // if T: PartialEq this now works!
    if vec1 == vec2 {
        // some code
    } else {
        // other code
    }
}
<span class="boring">}
</span></code></pre></pre>
<h4 id="hash"><a class="header" href="#hash">Hash</a></h4>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#generic-parameters">Generic Parameters</a></li>
<li><a href="#default-impls">Default Impls</a></li>
<li><a href="#derive-macros">Derive Macros</a></li>
<li><a href="#partialeq--eq">PartialEq &amp; Eq</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Hash {
    fn hash&lt;H: Hasher&gt;(&amp;self, state: &amp;mut H);

    // provided default impls
    fn hash_slice&lt;H: Hasher&gt;(data: &amp;[Self], state: &amp;mut H);
}
<span class="boring">}
</span></code></pre></pre>
<p>This trait is not associated with any operator, but the best time to talk about it is right after <code>PartialEq</code> &amp; <code>Eq</code> so here it is. <code>Hash</code> types can be hashed using a <code>Hasher</code>.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::hash::Hasher;
use std::hash::Hash;

struct Point {
    x: i32,
    y: i32,
}

impl Hash for Point {
    fn hash&lt;H: Hasher&gt;(&amp;self, hasher: &amp;mut H) {
        hasher.write_i32(self.x);
        hasher.write_i32(self.y);
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>There's a derive macro which generates the same impl as above:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>#[derive(Hash)]
struct Point {
    x: i32,
    y: i32,
}
<span class="boring">}
</span></code></pre></pre>
<p>If a type impls both <code>Hash</code> and <code>Eq</code> those impls must agree with each other such that for all <code>a</code> and <code>b</code> if <code>a == b</code> then <code>a.hash() == b.hash()</code>. So we should always use the derive macro to impl both or manually impl both, but not mix the two, otherwise we risk breaking the above invariant.</p>
<p>The main benefit of impling <code>Eq</code> and <code>Hash</code> for a type is that it allows us to store that type as keys in <code>HashMap</code>s and <code>HashSet</code>s.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::collections::HashSet;

// now our type can be stored
// in HashSets and HashMaps!
#[derive(PartialEq, Eq, Hash)]
struct Point {
    x: i32,
    y: i32,
}

fn example_hashset() {
    let mut points = HashSet::new();
    points.insert(Point { x: 0, y: 0 }); // ✅
}
<span class="boring">}
</span></code></pre></pre>
<h4 id="partialord--ord"><a class="header" href="#partialord--ord">PartialOrd &amp; Ord</a></h4>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#generic-parameters">Generic Parameters</a></li>
<li><a href="#default-impls">Default Impls</a></li>
<li><a href="#subtraits--supertraits">Subtraits &amp; Supertraits</a></li>
<li><a href="#derive-macros">Derive Macros</a></li>
<li><a href="#sized">Sized</a></li>
<li><a href="#partialeq--eq">PartialEq &amp; Eq</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>enum Ordering {
    Less,
    Equal,
    Greater,
}

trait PartialOrd&lt;Rhs = Self&gt;: PartialEq&lt;Rhs&gt; 
where
    Rhs: ?Sized, 
{
    fn partial_cmp(&amp;self, other: &amp;Rhs) -&gt; Option&lt;Ordering&gt;;

    // provided default impls
    fn lt(&amp;self, other: &amp;Rhs) -&gt; bool;
    fn le(&amp;self, other: &amp;Rhs) -&gt; bool;
    fn gt(&amp;self, other: &amp;Rhs) -&gt; bool;
    fn ge(&amp;self, other: &amp;Rhs) -&gt; bool;
}
<span class="boring">}
</span></code></pre></pre>
<p><code>PartialOrd&lt;Rhs&gt;</code> types can be compared to <code>Rhs</code> types using the <code>&lt;</code>, <code>&lt;=</code>, <code>&gt;</code>, and <code>&gt;=</code> operators.</p>
<p>All <code>PartialOrd</code> impls must ensure that comparisons are asymmetric and transitive. That means for all <code>a</code>, <code>b</code>, and <code>c</code>:</p>
<ul>
<li><code>a &lt; b</code> implies <code>!(a &gt; b)</code> (asymmetry)</li>
<li><code>a &lt; b &amp;&amp; b &lt; c</code> implies <code>a &lt; c</code> (transitivity)</li>
</ul>
<p><code>PartialOrd</code> is a subtrait of <code>PartialEq</code> and their impls must always agree with each other.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn must_always_agree&lt;T: PartialOrd + PartialEq&gt;(t1: T, t2: T) {
    assert_eq!(t1.partial_cmp(&amp;t2) == Some(Ordering::Equal), t1 == t2);
}
<span class="boring">}
</span></code></pre></pre>
<p><code>PartialOrd</code> refines <code>PartialEq</code> in the sense that when comparing <code>PartialEq</code> types we can check if they are equal or not equal, but when comparing <code>PartialOrd</code> types we can check if they are equal or not equal, and if they are not equal we can check if they are unequal because the first item is less than or greater than the second item.</p>
<p>By default <code>Rhs = Self</code> because we almost always want to compare instances of a type to each other, and not to instances of different types. This also automatically guarantees our impl is symmetric and transitive.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::cmp::Ordering;

#[derive(PartialEq, PartialOrd)]
struct Point {
    x: i32,
    y: i32
}

// Rhs == Self == Point
impl PartialOrd for Point {
    // impl automatically symmetric &amp; transitive
    fn partial_cmp(&amp;self, other: &amp;Point) -&gt; Option&lt;Ordering&gt; {
        Some(match self.x.cmp(&amp;other.x) {
            Ordering::Equal =&gt; self.y.cmp(&amp;other.y),
            ordering =&gt; ordering,
        })
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>If all the members of a type impl <code>PartialOrd</code> then it can be derived:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>#[derive(PartialEq, PartialOrd)]
struct Point {
    x: i32,
    y: i32,
}

#[derive(PartialEq, PartialOrd)]
enum Stoplight {
    Red,
    Yellow,
    Green,
}
<span class="boring">}
</span></code></pre></pre>
<p>The <code>PartialOrd</code> derive macro orders types based on the lexicographical order of their members:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// generates PartialOrd impl which orders
// Points based on x member first and
// y member second because that's the order
// they appear in the source code
#[derive(PartialOrd, PartialEq)]
struct Point {
    x: i32,
    y: i32,
}

// generates DIFFERENT PartialOrd impl
// which orders Points based on y member
// first and x member second
#[derive(PartialOrd, PartialEq)]
struct Point {
    y: i32,
    x: i32,
}
<span class="boring">}
</span></code></pre></pre>
<p><code>Ord</code> is a subtrait of <code>Eq</code> and <code>PartialOrd&lt;Self&gt;</code>:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Ord: Eq + PartialOrd&lt;Self&gt; {
    fn cmp(&amp;self, other: &amp;Self) -&gt; Ordering;

    // provided default impls
    fn max(self, other: Self) -&gt; Self;
    fn min(self, other: Self) -&gt; Self;
    fn clamp(self, min: Self, max: Self) -&gt; Self;
}
<span class="boring">}
</span></code></pre></pre>
<p>If we impl <code>Ord</code> for a type, on top of the asymmetry &amp; transitivity properties required by <code>PartialOrd</code>, we're also guaranteeing that the asymmetry is total, i.e. exactly one of <code>a &lt; b</code>, <code>a == b</code> or <code>a &gt; b</code> is true for any given <code>a</code> and <code>b</code>. In this sense <code>Ord</code> refines <code>Eq</code> and <code>PartialOrd</code> because it represents a stricter version of comparisons. If a type impls <code>Ord</code> we can use that impl to trivially impl <code>PartialOrd</code>, <code>PartialEq</code>, and <code>Eq</code>:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::cmp::Ordering;

// of course we can use the derive macros here
#[derive(Ord, PartialOrd, Eq, PartialEq)]
struct Point {
    x: i32,
    y: i32,
}

// note: as with PartialOrd, the Ord derive macro
// orders a type based on the lexicographical order
// of its members

// but here's the impls if we wrote them out by hand
impl Ord for Point {
    fn cmp(&amp;self, other: &amp;Self) -&gt; Ordering {
        match self.x.cmp(&amp;other.x) {
            Ordering::Equal =&gt; self.y.cmp(&amp;other.y),
            ordering =&gt; ordering,
        }
    }
}
impl PartialOrd for Point {
    fn partial_cmp(&amp;self, other: &amp;Self) -&gt; Option&lt;Ordering&gt; {
        Some(self.cmp(other))
    }
}
impl PartialEq for Point {
    fn eq(&amp;self, other: &amp;Self) -&gt; bool {
        self.cmp(other) == Ordering::Equal
    }
}
impl Eq for Point {}
<span class="boring">}
</span></code></pre></pre>
<p>Floats impl <code>PartialOrd</code> but not <code>Ord</code> because both <code>NaN &lt; 0 == false</code> and <code>NaN &gt;= 0 == false</code> are simultaneously true. Almost all other <code>PartialOrd</code> types are trivially <code>Ord</code>, unless of course if they contain floats.</p>
<p>Once a type impls <code>Ord</code> we can store it in <code>BTreeMap</code>s and <code>BTreeSet</code>s as well as easily sort it using the <code>sort()</code> method on slices and any types which deref to slices such as arrays, <code>Vec</code>s, and <code>VecDeque</code>s.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::collections::BTreeSet;

// now our type can be stored
// in BTreeSets and BTreeMaps!
#[derive(Ord, PartialOrd, PartialEq, Eq)]
struct Point {
    x: i32,
    y: i32,
}

fn example_btreeset() {
    let mut points = BTreeSet::new();
    points.insert(Point { x: 0, y: 0 }); // ✅
}

// we can also .sort() Ord types in collections!
fn example_sort&lt;T: Ord&gt;(mut sortable: Vec&lt;T&gt;) -&gt; Vec&lt;T&gt; {
    sortable.sort();
    sortable
}
<span class="boring">}
</span></code></pre></pre>
<h3 id="arithmetic-traits"><a class="header" href="#arithmetic-traits">Arithmetic Traits</a></h3>
<div class="table-wrapper"><table><thead><tr><th>Trait(s)</th><th>Category</th><th>Operator(s)</th><th>Description</th></tr></thead><tbody>
<tr><td><code>Add</code></td><td>arithmetic</td><td><code>+</code></td><td>addition</td></tr>
<tr><td><code>AddAssign</code></td><td>arithmetic</td><td><code>+=</code></td><td>addition assignment</td></tr>
<tr><td><code>BitAnd</code></td><td>arithmetic</td><td><code>&amp;</code></td><td>bitwise AND</td></tr>
<tr><td><code>BitAndAssign</code></td><td>arithmetic</td><td><code>&amp;=</code></td><td>bitwise assignment</td></tr>
<tr><td><code>BitXor</code></td><td>arithmetic</td><td><code>^</code></td><td>bitwise XOR</td></tr>
<tr><td><code>BitXorAssign</code></td><td>arithmetic</td><td><code>^=</code></td><td>bitwise XOR assignment</td></tr>
<tr><td><code>Div</code></td><td>arithmetic</td><td><code>/</code></td><td>division</td></tr>
<tr><td><code>DivAssign</code></td><td>arithmetic</td><td><code>/=</code></td><td>division assignment</td></tr>
<tr><td><code>Mul</code></td><td>arithmetic</td><td><code>*</code></td><td>multiplication</td></tr>
<tr><td><code>MulAssign</code></td><td>arithmetic</td><td><code>*=</code></td><td>multiplication assignment</td></tr>
<tr><td><code>Neg</code></td><td>arithmetic</td><td><code>-</code></td><td>unary negation</td></tr>
<tr><td><code>Not</code></td><td>arithmetic</td><td><code>!</code></td><td>unary logical negation</td></tr>
<tr><td><code>Rem</code></td><td>arithmetic</td><td><code>%</code></td><td>remainder</td></tr>
<tr><td><code>RemAssign</code></td><td>arithmetic</td><td><code>%=</code></td><td>remainder assignment</td></tr>
<tr><td><code>Shl</code></td><td>arithmetic</td><td><code>&lt;&lt;</code></td><td>left shift</td></tr>
<tr><td><code>ShlAssign</code></td><td>arithmetic</td><td><code>&lt;&lt;=</code></td><td>left shift assignment</td></tr>
<tr><td><code>Shr</code></td><td>arithmetic</td><td><code>&gt;&gt;</code></td><td>right shift</td></tr>
<tr><td><code>ShrAssign</code></td><td>arithmetic</td><td><code>&gt;&gt;=</code></td><td>right shift assignment</td></tr>
<tr><td><code>Sub</code></td><td>arithmetic</td><td><code>-</code></td><td>subtraction</td></tr>
<tr><td><code>SubAssign</code></td><td>arithmetic</td><td><code>-=</code></td><td>subtraction assignment</td></tr>
</tbody></table>
</div>
<p>Going over all of these would be very redundant. Most of these only apply to number types anyway. We'll only go over <code>Add</code> and <code>AddAssign</code> since the <code>+</code> operator is commonly overloaded to do other stuff like adding items to collections or concatenating things together, that way we cover the most interesting ground and don't repeat ourselves.</p>
<h4 id="add--addassign"><a class="header" href="#add--addassign">Add &amp; AddAssign</a></h4>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#associated-types">Associated Types</a></li>
<li><a href="#generic-parameters">Generic Parameters</a></li>
<li><a href="#generic-types-vs-associated-types">Generic Types vs Associated Types</a></li>
<li><a href="#derive-macros">Derive Macros</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Add&lt;Rhs = Self&gt; {
    type Output;
    fn add(self, rhs: Rhs) -&gt; Self::Output;
}
<span class="boring">}
</span></code></pre></pre>
<p><code>Add&lt;Rhs, Output = T&gt;</code> types can be added to <code>Rhs</code> types and will produce <code>T</code> as output.</p>
<p>Example <code>Add&lt;Point, Output = Point&gt;</code> impl for <code>Point</code>:</p>
<pre><pre class="playground"><code class="language-rust">#[derive(Clone, Copy)]
struct Point {
    x: i32,
    y: i32,
}

impl Add for Point {
    type Output = Point;
    fn add(self, rhs: Point) -&gt; Point {
        Point {
            x: self.x + rhs.x,
            y: self.y + rhs.y,
        }
    }
}

fn main() {
    let p1 = Point { x: 1, y: 2 };
    let p2 = Point { x: 3, y: 4 };
    let p3 = p1 + p2;
    assert_eq!(p3.x, p1.x + p2.x); // ✅
    assert_eq!(p3.y, p1.y + p2.y); // ✅
}
</code></pre></pre>
<p>But what if we only had references to <code>Point</code>s? Can we still add them then? Let's try:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    let p1 = Point { x: 1, y: 2 };
    let p2 = Point { x: 3, y: 4 };
    let p3 = &amp;p1 + &amp;p2; // ❌
}
</code></pre></pre>
<p>Unfortunately not. The compiler throws:</p>
<pre><code class="language-none">error[E0369]: cannot add `&amp;Point` to `&amp;Point`
  --&gt; src/main.rs:50:25
   |
50 |     let p3: Point = &amp;p1 + &amp;p2;
   |                     --- ^ --- &amp;Point
   |                     |
   |                     &amp;Point
   |
   = note: an implementation of `std::ops::Add` might be missing for `&amp;Point`
</code></pre>
<p>Within Rust's type system, for some type <code>T</code>, the types <code>T</code>, <code>&amp;T</code>, and <code>&amp;mut T</code> are all treated as unique distinct types which means we have to provide trait impls for each of them separately. Let's define an <code>Add</code> impl for <code>&amp;Point</code>:</p>
<pre><pre class="playground"><code class="language-rust">impl Add for &amp;Point {
    type Output = Point;
    fn add(self, rhs: &amp;Point) -&gt; Point {
        Point {
            x: self.x + rhs.x,
            y: self.y + rhs.y,
        }
    }
}

fn main() {
    let p1 = Point { x: 1, y: 2 };
    let p2 = Point { x: 3, y: 4 };
    let p3 = &amp;p1 + &amp;p2; // ✅
    assert_eq!(p3.x, p1.x + p2.x); // ✅
    assert_eq!(p3.y, p1.y + p2.y); // ✅
}
</code></pre></pre>
<p>However, something still doesn't feel quite right. We have two separate impls of <code>Add</code> for <code>Point</code> and <code>&amp;Point</code> and they <em>happen</em> to do the same thing currently but there's no guarantee that they will in the future! For example, let's say we decide that when we add two <code>Point</code>s together we want to create a <code>Line</code> containing those two <code>Point</code>s instead of creating a new <code>Point</code>, we'd update our <code>Add</code> impl like this:</p>
<pre><pre class="playground"><code class="language-rust">use std::ops::Add;

#[derive(Copy, Clone)]
struct Point {
    x: i32,
    y: i32,
}

#[derive(Copy, Clone)]
struct Line {
    start: Point,
    end: Point,
}

// we updated this impl
impl Add for Point {
    type Output = Line;
    fn add(self, rhs: Point) -&gt; Line {
        Line {
            start: self,
            end: rhs,
        }
    }
}

// but forgot to update this impl, uh oh!
impl Add for &amp;Point {
    type Output = Point;
    fn add(self, rhs: &amp;Point) -&gt; Point {
        Point {
            x: self.x + rhs.x,
            y: self.y + rhs.y,
        }
    }
}

fn main() {
    let p1 = Point { x: 1, y: 2 };
    let p2 = Point { x: 3, y: 4 };
    let line: Line = p1 + p2; // ✅

    let p1 = Point { x: 1, y: 2 };
    let p2 = Point { x: 3, y: 4 };
    let line: Line = &amp;p1 + &amp;p2; // ❌ expected Line, found Point
}
</code></pre></pre>
<p>Our current impl of <code>Add</code> for <code>&amp;Point</code> creates an unnecessary maintenance burden, we want the impl to match <code>Point</code>'s impl without having to manually update it every time we change <code>Point</code>'s impl. We'd like to keep our code as DRY (Don't Repeat Yourself) as possible. Luckily this is achievable:</p>
<pre><pre class="playground"><code class="language-rust">// updated, DRY impl
impl Add for &amp;Point {
    type Output = &lt;Point as Add&gt;::Output;
    fn add(self, rhs: &amp;Point) -&gt; Self::Output {
        Point::add(*self, *rhs)
    }
}

fn main() {
    let p1 = Point { x: 1, y: 2 };
    let p2 = Point { x: 3, y: 4 };
    let line: Line = p1 + p2; // ✅

    let p1 = Point { x: 1, y: 2 };
    let p2 = Point { x: 3, y: 4 };
    let line: Line = &amp;p1 + &amp;p2; // ✅
}
</code></pre></pre>
<p><code>AddAssign&lt;Rhs&gt;</code> types allow us to add + assign <code>Rhs</code> types to them. The trait declaration:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait AddAssign&lt;Rhs = Self&gt; {
    fn add_assign(&amp;mut self, rhs: Rhs);
}
<span class="boring">}
</span></code></pre></pre>
<p>Example impls for <code>Point</code> and <code>&amp;Point</code>:</p>
<pre><pre class="playground"><code class="language-rust">use std::ops::AddAssign;

#[derive(Copy, Clone)]
struct Point {
    x: i32,
    y: i32
}

impl AddAssign for Point {
    fn add_assign(&amp;mut self, rhs: Point) {
        self.x += rhs.x;
        self.y += rhs.y;
    }
}

impl AddAssign&lt;&amp;Point&gt; for Point {
    fn add_assign(&amp;mut self, rhs: &amp;Point) {
        Point::add_assign(self, *rhs);
    }
}

fn main() {
    let mut p1 = Point { x: 1, y: 2 };
    let p2 = Point { x: 3, y: 4 };
    p1 += &amp;p2;
    p1 += p2;
    assert!(p1.x == 7 &amp;&amp; p1.y == 10);
}
</code></pre></pre>
<h3 id="closure-traits"><a class="header" href="#closure-traits">Closure Traits</a></h3>
<div class="table-wrapper"><table><thead><tr><th>Trait(s)</th><th>Category</th><th>Operator(s)</th><th>Description</th></tr></thead><tbody>
<tr><td><code>Fn</code></td><td>closure</td><td><code>(...args)</code></td><td>immutable closure invocation</td></tr>
<tr><td><code>FnMut</code></td><td>closure</td><td><code>(...args)</code></td><td>mutable closure invocation</td></tr>
<tr><td><code>FnOnce</code></td><td>closure</td><td><code>(...args)</code></td><td>one-time closure invocation</td></tr>
</tbody></table>
</div>
<h4 id="fnonce-fnmut--fn"><a class="header" href="#fnonce-fnmut--fn">FnOnce, FnMut, &amp; Fn</a></h4>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#associated-types">Associated Types</a></li>
<li><a href="#generic-parameters">Generic Parameters</a></li>
<li><a href="#generic-types-vs-associated-types">Generic Types vs Associated Types</a></li>
<li><a href="#subtraits--supertraits">Subtraits &amp; Supertraits</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait FnOnce&lt;Args&gt; {
    type Output;
    fn call_once(self, args: Args) -&gt; Self::Output;
}

trait FnMut&lt;Args&gt;: FnOnce&lt;Args&gt; {
    fn call_mut(&amp;mut self, args: Args) -&gt; Self::Output;
}

trait Fn&lt;Args&gt;: FnMut&lt;Args&gt; {
    fn call(&amp;self, args: Args) -&gt; Self::Output;
}
<span class="boring">}
</span></code></pre></pre>
<p>Although these traits exist it's not possible to impl them for our own types in stable Rust. The only types we can create which impl these traits are closures. Depending on what the closure captures from its environment determines whether it impls <code>FnOnce</code>, <code>FnMut</code>, or <code>Fn</code>.</p>
<p>An <code>FnOnce</code> closure can only be called once because it consumes some value as part of its execution:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    let range = 0..10;
    let get_range_count = || range.count();
    assert_eq!(get_range_count(), 10); // ✅
    get_range_count(); // ❌
}
</code></pre></pre>
<p>The <code>.count()</code> method on iterators consumes the iterator so it can only be called once. Hence our closure can only be called once. Which is why when we try to call it a second time we get this error:</p>
<pre><code class="language-none">error[E0382]: use of moved value: `get_range_count`
 --&gt; src/main.rs:5:5
  |
4 |     assert_eq!(get_range_count(), 10);
  |                ----------------- `get_range_count` moved due to this call
5 |     get_range_count();
  |     ^^^^^^^^^^^^^^^ value used here after move
  |
note: closure cannot be invoked more than once because it moves the variable `range` out of its environment
 --&gt; src/main.rs:3:30
  |
3 |     let get_range_count = || range.count();
  |                              ^^^^^
note: this value implements `FnOnce`, which causes it to be moved when called
 --&gt; src/main.rs:4:16
  |
4 |     assert_eq!(get_range_count(), 10);
  |                ^^^^^^^^^^^^^^^
</code></pre>
<p>An <code>FnMut</code> closure can be called multiple times and can also mutate variables it has captured from its environment. We might say <code>FnMut</code> closures perform side-effects or are stateful. Here's an example of a closure that filters out all non-ascending values from an iterator by keeping track of the smallest value it has seen so far:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    let nums = vec![0, 4, 2, 8, 10, 7, 15, 18, 13];
    let mut min = i32::MIN;
    let ascending = nums.into_iter().filter(|&amp;n| {
        if n &lt;= min {
            false
        } else {
            min = n;
            true
        }
    }).collect::&lt;Vec&lt;_&gt;&gt;();
    assert_eq!(vec![0, 4, 8, 10, 15, 18], ascending); // ✅
}
</code></pre></pre>
<p><code>FnMut</code> refines <code>FnOnce</code> in the sense that <code>FnOnce</code> requires taking ownership of its arguments and can only be called once, but <code>FnMut</code> requires only taking mutable references and can be called multiple times. <code>FnMut</code> can be used anywhere <code>FnOnce</code> can be used.</p>
<p>An <code>Fn</code> closure can be called multiple times and does not mutate any variables it has captured from its environment. We might say <code>Fn</code> closures have no side-effects or are stateless. Here's an example closure that filters out all values less than some stack variable it captures from its environment from an iterator:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    let nums = vec![0, 4, 2, 8, 10, 7, 15, 18, 13];
    let min = 9;
    let greater_than_9 = nums.into_iter().filter(|&amp;n| n &gt; min).collect::&lt;Vec&lt;_&gt;&gt;();
    assert_eq!(vec![10, 15, 18, 13], greater_than_9); // ✅
}
</code></pre></pre>
<p><code>Fn</code> refines <code>FnMut</code> in the sense that <code>FnMut</code> requires mutable references and can be called multiple times, but <code>Fn</code> only requires immutable references and can be called multiple times. <code>Fn</code> can be used anywhere <code>FnMut</code> can be used, which includes anywhere <code>FnOnce</code> can be used.</p>
<p>If a closure doesn't capture anything from its environment it's technically not a closure, but just an anonymously declared inline function, and can be casted to, used, and passed around as a regular function pointer, i.e. <code>fn</code>. Function pointers can be used anywhere <code>Fn</code> can be used, which includes anwhere <code>FnMut</code> and <code>FnOnce</code> can be used.</p>
<pre><pre class="playground"><code class="language-rust">fn add_one(x: i32) -&gt; i32 {
    x + 1
}

fn main() {
    let mut fn_ptr: fn(i32) -&gt; i32 = add_one;
    assert_eq!(fn_ptr(1), 2); // ✅
    
    // capture-less closure cast to fn pointer
    fn_ptr = |x| x + 1; // same as add_one
    assert_eq!(fn_ptr(1), 2); // ✅
}
</code></pre></pre>
<p>Example of passing a regular function pointer in place of a closure:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    let nums = vec![-1, 1, -2, 2, -3, 3];
    let absolutes: Vec&lt;i32&gt; = nums.into_iter().map(i32::abs).collect();
    assert_eq!(vec![1, 1, 2, 2, 3, 3], absolutes); // ✅
}
</code></pre></pre>
<h3 id="other-traits"><a class="header" href="#other-traits">Other Traits</a></h3>
<div class="table-wrapper"><table><thead><tr><th>Trait(s)</th><th>Category</th><th>Operator(s)</th><th>Description</th></tr></thead><tbody>
<tr><td><code>Deref</code></td><td>other</td><td><code>*</code></td><td>immutable dereference</td></tr>
<tr><td><code>DerefMut</code></td><td>other</td><td><code>*</code></td><td>mutable dereference</td></tr>
<tr><td><code>Drop</code></td><td>other</td><td>-</td><td>type destructor</td></tr>
<tr><td><code>Index</code></td><td>other</td><td><code>[]</code></td><td>immutable index</td></tr>
<tr><td><code>IndexMut</code></td><td>other</td><td><code>[]</code></td><td>mutable index</td></tr>
<tr><td><code>RangeBounds</code></td><td>other</td><td><code>..</code></td><td>range</td></tr>
</tbody></table>
</div>
<h4 id="deref--derefmut"><a class="header" href="#deref--derefmut">Deref &amp; DerefMut</a></h4>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#associated-types">Associated Types</a></li>
<li><a href="#subtraits--supertraits">Subtraits &amp; Supertraits</a></li>
<li><a href="#sized">Sized</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Deref {
    type Target: ?Sized;
    fn deref(&amp;self) -&gt; &amp;Self::Target;
}

trait DerefMut: Deref {
    fn deref_mut(&amp;mut self) -&gt; &amp;mut Self::Target;
}
<span class="boring">}
</span></code></pre></pre>
<p><code>Deref&lt;Target = T&gt;</code> types can be dereferenced to <code>T</code> types using the dereference operator <code>*</code>. This has obvious use-cases for smart pointer types like <code>Box</code> and <code>Rc</code>. However, we rarely see the dereference operator explicitly used in Rust code, and that's because of a Rust feature called <em>deref coercion</em>.</p>
<p>Rust automatically dereferences types when they're being passed as function arguments, returned from a function, or used as part of a method call. This is the reason why we can pass <code>&amp;String</code> and <code>&amp;Vec&lt;T&gt;</code> to functions expecting <code>&amp;str</code> and <code>&amp;[T]</code> because <code>String</code> impls <code>Deref&lt;Target = str&gt;</code> and <code>Vec&lt;T&gt;</code> impls <code>Deref&lt;Target = [T]&gt;</code>.</p>
<p><code>Deref</code> and <code>DerefMut</code> should only be implemented for smart pointer types. The most common way people attempt to misuse and abuse these traits is to try to shoehorn some kind of OOP-style data inheritance into Rust. This does not work. Rust is not OOP. Let's examine a few different situations where, how, and why it does not work. Let's start with this example:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::ops::Deref;

struct Human {
    health_points: u32,
}

enum Weapon {
    Spear,
    Axe,
    Sword,
}

// a Soldier is just a Human with a Weapon
struct Soldier {
    human: Human,
    weapon: Weapon,
}

impl Deref for Soldier {
    type Target = Human;
    fn deref(&amp;self) -&gt; &amp;Human {
        &amp;self.human
    }
}

enum Mount {
    Horse,
    Donkey,
    Cow,
}

// a Knight is just a Soldier with a Mount
struct Knight {
    soldier: Soldier,
    mount: Mount,
}

impl Deref for Knight {
    type Target = Soldier;
    fn deref(&amp;self) -&gt; &amp;Soldier {
        &amp;self.soldier
    }
}

enum Spell {
    MagicMissile,
    FireBolt,
    ThornWhip,
}

// a Mage is just a Human who can cast Spells
struct Mage {
    human: Human,
    spells: Vec&lt;Spell&gt;,
}

impl Deref for Mage {
    type Target = Human;
    fn deref(&amp;self) -&gt; &amp;Human {
        &amp;self.human
    }
}

enum Staff {
    Wooden,
    Metallic,
    Plastic,
}

// a Wizard is just a Mage with a Staff
struct Wizard {
    mage: Mage,
    staff: Staff,
}

impl Deref for Wizard {
    type Target = Mage;
    fn deref(&amp;self) -&gt; &amp;Mage {
        &amp;self.mage
    }
}

fn borrows_human(human: &amp;Human) {}
fn borrows_soldier(soldier: &amp;Soldier) {}
fn borrows_knight(knight: &amp;Knight) {}
fn borrows_mage(mage: &amp;Mage) {}
fn borrows_wizard(wizard: &amp;Wizard) {}

fn example(human: Human, soldier: Soldier, knight: Knight, mage: Mage, wizard: Wizard) {
    // all types can be used as Humans
    borrows_human(&amp;human);
    borrows_human(&amp;soldier);
    borrows_human(&amp;knight);
    borrows_human(&amp;mage);
    borrows_human(&amp;wizard);
    // Knights can be used as Soldiers
    borrows_soldier(&amp;soldier);
    borrows_soldier(&amp;knight);
    // Wizards can be used as Mages
    borrows_mage(&amp;mage);
    borrows_mage(&amp;wizard);
    // Knights &amp; Wizards passed as themselves
    borrows_knight(&amp;knight);
    borrows_wizard(&amp;wizard);
}
<span class="boring">}
</span></code></pre></pre>
<p>So at first glance the above looks pretty good! However it quickly breaks down to scrutiny. First of all, deref coercion only works on references, so it doesn't work when we actually want to pass ownership:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn takes_human(human: Human) {}

fn example(human: Human, soldier: Soldier, knight: Knight, mage: Mage, wizard: Wizard) {
    // all types CANNOT be used as Humans
    takes_human(human);
    takes_human(soldier); // ❌
    takes_human(knight); // ❌
    takes_human(mage); // ❌
    takes_human(wizard); // ❌
}
<span class="boring">}
</span></code></pre></pre>
<p>Furthermore, deref coercion doesn't work in generic contexts. Let's say we impl some trait only on humans:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Rest {
    fn rest(&amp;self);
}

impl Rest for Human {
    fn rest(&amp;self) {}
}

fn take_rest&lt;T: Rest&gt;(rester: &amp;T) {
    rester.rest()
}

fn example(human: Human, soldier: Soldier, knight: Knight, mage: Mage, wizard: Wizard) {
    // all types CANNOT be used as Rest types, only Human
    take_rest(&amp;human);
    take_rest(&amp;soldier); // ❌
    take_rest(&amp;knight); // ❌
    take_rest(&amp;mage); // ❌
    take_rest(&amp;wizard); // ❌
}
<span class="boring">}
</span></code></pre></pre>
<p>Also, although deref coercion works in a lot of places it doesn't work everywhere. It doesn't work on operands, even though operators are just syntax sugar for method calls. Let's say, to be cute, we wanted <code>Mage</code>s to learn <code>Spell</code>s using the <code>+=</code> operator:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>impl DerefMut for Wizard {
    fn deref_mut(&amp;mut self) -&gt; &amp;mut Mage {
        &amp;mut self.mage
    }
}

impl AddAssign&lt;Spell&gt; for Mage {
    fn add_assign(&amp;mut self, spell: Spell) {
        self.spells.push(spell);
    }
}

fn example(mut mage: Mage, mut wizard: Wizard, spell: Spell) {
    mage += spell;
    wizard += spell; // ❌ wizard not coerced to mage here
    wizard.add_assign(spell); // oof, we have to call it like this 🤦
}
<span class="boring">}
</span></code></pre></pre>
<p>In languages with OOP-style data inheritance the value of <code>self</code> within a method is always equal to the type which called the method but in the case of Rust the value of <code>self</code> is always equal to the type which implemented the method:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct Human {
    profession: &amp;'static str,
    health_points: u32,
}

impl Human {
    // self will always be a Human here, even if we call it on a Soldier
    fn state_profession(&amp;self) {
        println!(&quot;I'm a {}!&quot;, self.profession);
    }
}

struct Soldier {
    profession: &amp;'static str,
    human: Human,
    weapon: Weapon,
}

fn example(soldier: &amp;Soldier) {
    assert_eq!(&quot;servant&quot;, soldier.human.profession);
    assert_eq!(&quot;spearman&quot;, soldier.profession);
    soldier.human.state_profession(); // prints &quot;I'm a servant!&quot;
    soldier.state_profession(); // still prints &quot;I'm a servant!&quot; 🤦
}
<span class="boring">}
</span></code></pre></pre>
<p>The above gotcha is especially damning when impling <code>Deref</code> or <code>DerefMut</code> on a newtype. Let's say we want to create a <code>SortedVec</code> type which is just a <code>Vec</code> but it's always in sorted order. Here's how we might do that:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct SortedVec&lt;T: Ord&gt;(Vec&lt;T&gt;);

impl&lt;T: Ord&gt; SortedVec&lt;T&gt; {
    fn new(mut vec: Vec&lt;T&gt;) -&gt; Self {
        vec.sort();
        SortedVec(vec)
    }
    fn push(&amp;mut self, t: T) {
        self.0.push(t);
        self.0.sort();
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>Obviously we cannot impl <code>DerefMut&lt;Target = Vec&lt;T&gt;&gt;</code> here or anyone using <code>SortedVec</code> would be able to trivially break the sorted order. However, impling <code>Deref&lt;Target = Vec&lt;T&gt;&gt;</code> surely must be safe, right? Try to spot the bug in the program below:</p>
<pre><pre class="playground"><code class="language-rust">use std::ops::Deref;

struct SortedVec&lt;T: Ord&gt;(Vec&lt;T&gt;);

impl&lt;T: Ord&gt; SortedVec&lt;T&gt; {
    fn new(mut vec: Vec&lt;T&gt;) -&gt; Self {
        vec.sort();
        SortedVec(vec)
    }
    fn push(&amp;mut self, t: T) {
        self.0.push(t);
        self.0.sort();
    }
}

impl&lt;T: Ord&gt; Deref for SortedVec&lt;T&gt; {
    type Target = Vec&lt;T&gt;;
    fn deref(&amp;self) -&gt; &amp;Vec&lt;T&gt; {
        &amp;self.0
    }
}

fn main() {
    let sorted = SortedVec::new(vec![2, 8, 6, 3]);
    sorted.push(1);
    let sortedClone = sorted.clone();
    sortedClone.push(4);
}
</code></pre></pre>
<p>We never implemented <code>Clone</code> for <code>SortedVec</code> so when we call the <code>.clone()</code> method the compiler is using deref coercion to resolve that method call on <code>Vec</code> and so it returns a <code>Vec</code> and not a <code>SortedVec</code>!</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    let sorted: SortedVec&lt;i32&gt; = SortedVec::new(vec![2, 8, 6, 3]);
    sorted.push(1); // still sorted

    // calling clone on SortedVec actually returns a Vec 🤦
    let sortedClone: Vec&lt;i32&gt; = sorted.clone();
    sortedClone.push(4); // sortedClone no longer sorted 💀
}
</code></pre></pre>
<p>Anyway, none of the above limitations, constraints, or gotchas are faults of Rust because Rust was never designed to be an OO language or to support any OOP patterns in the first place.</p>
<p>The main takeaway from this section is do not try to be cute or clever with <code>Deref</code> and <code>DerefMut</code> impls. They're really only appropriate for smart pointer types, which can only be implemented within the standard library for now as smart pointer types currently require unstable features and compiler magic to work. If we want functionality and behavior similar to <code>Deref</code> and <code>DerefMut</code> then what we're actually probably looking for is <code>AsRef</code> and <code>AsMut</code> which we'll get to later.</p>
<h4 id="index--indexmut"><a class="header" href="#index--indexmut">Index &amp; IndexMut</a></h4>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#associated-types">Associated Types</a></li>
<li><a href="#generic-parameters">Generic Parameters</a></li>
<li><a href="#generic-types-vs-associated-types">Generic Types vs Associated Types</a></li>
<li><a href="#subtraits--supertraits">Subtraits &amp; Supertraits</a></li>
<li><a href="#sized">Sized</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Index&lt;Idx: ?Sized&gt; {
    type Output: ?Sized;
    fn index(&amp;self, index: Idx) -&gt; &amp;Self::Output;
}

trait IndexMut&lt;Idx&gt;: Index&lt;Idx&gt; where Idx: ?Sized {
    fn index_mut(&amp;mut self, index: Idx) -&gt; &amp;mut Self::Output;
}
<span class="boring">}
</span></code></pre></pre>
<p>We can index <code>[]</code> into <code>Index&lt;T, Output = U&gt;</code> types with <code>T</code> values and the index operation will return <code>&amp;U</code> values. For syntax sugar, the compiler auto inserts a deref operator <code>*</code> in front of any value returned from an index operation:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    // Vec&lt;i32&gt; impls Index&lt;usize, Output = i32&gt; so
    // indexing Vec&lt;i32&gt; should produce &amp;i32s and yet...
    let vec = vec![1, 2, 3, 4, 5];
    let num_ref: &amp;i32 = vec[0]; // ❌ expected &amp;i32 found i32
    
    // above line actually desugars to
    let num_ref: &amp;i32 = *vec[0]; // ❌ expected &amp;i32 found i32

    // both of these alternatives work
    let num: i32 = vec[0]; // ✅
    let num_ref = &amp;vec[0]; // ✅
}
</code></pre></pre>
<p>It's kinda confusing at first, because it seems like the <code>Index</code> trait does not follow its own method signature, but really it's just questionable syntax sugar.</p>
<p>Since <code>Idx</code> is a generic type the <code>Index</code> trait can be implemented many times for a given type, and in the case of <code>Vec&lt;T&gt;</code> not only can we index into it using <code>usize</code> but we can also index into it using <code>Range&lt;usize&gt;</code>s to get slices.</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
    let vec = vec![1, 2, 3, 4, 5];
    assert_eq!(&amp;vec[..], &amp;[1, 2, 3, 4, 5]); // ✅
    assert_eq!(&amp;vec[1..], &amp;[2, 3, 4, 5]); // ✅
    assert_eq!(&amp;vec[..4], &amp;[1, 2, 3, 4]); // ✅
    assert_eq!(&amp;vec[1..4], &amp;[2, 3, 4]); // ✅
}
</code></pre></pre>
<p>To show off how we might impl <code>Index</code> ourselves here's a fun example which shows how we can use a newtype and the <code>Index</code> trait to impl wrapping indexes and negative indexes on a <code>Vec</code>:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::ops::Index;

struct WrappingIndex&lt;T&gt;(Vec&lt;T&gt;);

impl&lt;T&gt; Index&lt;usize&gt; for WrappingIndex&lt;T&gt; {
    type Output = T;
    fn index(&amp;self, index: usize) -&gt; &amp;T {
        &amp;self.0[index % self.0.len()]
    }
}

impl&lt;T&gt; Index&lt;i128&gt; for WrappingIndex&lt;T&gt; {
    type Output = T;
    fn index(&amp;self, index: i128) -&gt; &amp;T {
        let self_len = self.0.len() as i128;
        let idx = (((index % self_len) + self_len) % self_len) as usize;
        &amp;self.0[idx]
    }
}

#[test] // ✅
fn indexes() {
    let wrapping_vec = WrappingIndex(vec![1, 2, 3]);
    assert_eq!(1, wrapping_vec[0_usize]);
    assert_eq!(2, wrapping_vec[1_usize]);
    assert_eq!(3, wrapping_vec[2_usize]);
}

#[test] // ✅
fn wrapping_indexes() {
    let wrapping_vec = WrappingIndex(vec![1, 2, 3]);
    assert_eq!(1, wrapping_vec[3_usize]);
    assert_eq!(2, wrapping_vec[4_usize]);
    assert_eq!(3, wrapping_vec[5_usize]);
}

#[test] // ✅
fn neg_indexes() {
    let wrapping_vec = WrappingIndex(vec![1, 2, 3]);
    assert_eq!(1, wrapping_vec[-3_i128]);
    assert_eq!(2, wrapping_vec[-2_i128]);
    assert_eq!(3, wrapping_vec[-1_i128]);
}

#[test] // ✅
fn wrapping_neg_indexes() {
    let wrapping_vec = WrappingIndex(vec![1, 2, 3]);
    assert_eq!(1, wrapping_vec[-6_i128]);
    assert_eq!(2, wrapping_vec[-5_i128]);
    assert_eq!(3, wrapping_vec[-4_i128]);
}
<span class="boring">}
</span></code></pre></pre>
<p>There's no requirement that the <code>Idx</code> type has to be a number type or a <code>Range</code>, it could be an enum! Here's an example using basketball positions to index into a basketball team to retrieve players on the team:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::ops::Index;

enum BasketballPosition {
    PointGuard,
    ShootingGuard,
    Center,
    PowerForward,
    SmallForward,
}

struct BasketballPlayer {
    name: &amp;'static str,
    position: BasketballPosition,
}

struct BasketballTeam {
    point_guard: BasketballPlayer,
    shooting_guard: BasketballPlayer,
    center: BasketballPlayer,
    power_forward: BasketballPlayer,
    small_forward: BasketballPlayer,
}

impl Index&lt;BasketballPosition&gt; for BasketballTeam {
    type Output = BasketballPlayer;
    fn index(&amp;self, position: BasketballPosition) -&gt; &amp;BasketballPlayer {
        match position {
            BasketballPosition::PointGuard =&gt; &amp;self.point_guard,
            BasketballPosition::ShootingGuard =&gt; &amp;self.shooting_guard,
            BasketballPosition::Center =&gt; &amp;self.center,
            BasketballPosition::PowerForward =&gt; &amp;self.power_forward,
            BasketballPosition::SmallForward =&gt; &amp;self.small_forward,
        }
    }
}
<span class="boring">}
</span></code></pre></pre>
<h4 id="drop"><a class="header" href="#drop">Drop</a></h4>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#methods">Methods</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Drop {
    fn drop(&amp;mut self);
}
<span class="boring">}
</span></code></pre></pre>
<p>If a type impls <code>Drop</code> then <code>drop</code> will be called on the type when it goes out of scope but before it's destroyed. We will rarely need to impl this for our types but a good example of where it's useful is if a type holds on to some external resources which needs to be cleaned up when the type is destroyed.</p>
<p>There's a <code>BufWriter</code> type in the standard library that allows us to buffer writes to <code>Write</code> types. However, what if the <code>BufWriter</code> gets destroyed before the content in its buffer has been flushed to the underlying <code>Write</code> type? Thankfully that's not possible! The <code>BufWriter</code> impls the <code>Drop</code> trait so that <code>flush</code> is always called on it whenever it goes out of scope!</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>impl&lt;W: Write&gt; Drop for BufWriter&lt;W&gt; {
    fn drop(&amp;mut self) {
        self.flush_buf();
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>Also, <code>Mutex</code>s in Rust don't have <code>unlock()</code> methods because they don't need them! Calling <code>lock()</code> on a <code>Mutex</code> returns a <code>MutexGuard</code> which automatically unlocks the <code>Mutex</code> when it goes out of scope thanks to its <code>Drop</code> impl:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>impl&lt;T: ?Sized&gt; Drop for MutexGuard&lt;'_, T&gt; {
    fn drop(&amp;mut self) {
        unsafe {
            self.lock.inner.raw_unlock();
        }
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>In general, if you're impling an abstraction over some resource that needs to be cleaned up after use then that's a great reason to make use of the <code>Drop</code> trait.</p>
<h2 id="conversion-traits"><a class="header" href="#conversion-traits">Conversion Traits</a></h2>
<h3 id="from--into"><a class="header" href="#from--into">From &amp; Into</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#functions">Functions</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#generic-parameters">Generic Parameters</a></li>
<li><a href="#generic-blanket-impls">Generic Blanket Impls</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait From&lt;T&gt; {
    fn from(T) -&gt; Self;
}
<span class="boring">}
</span></code></pre></pre>
<p><code>From&lt;T&gt;</code> types allow us to convert <code>T</code> into <code>Self</code>.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Into&lt;T&gt; {
    fn into(self) -&gt; T;
}
<span class="boring">}
</span></code></pre></pre>
<p><code>Into&lt;T&gt;</code> types allow us to convert <code>Self</code> into <code>T</code>.</p>
<p>These traits are two different sides of the same coin. We can only impl <code>From&lt;T&gt;</code> for our types because the <code>Into&lt;T&gt;</code> impl is automatically provided by this generic blanket impl:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>impl&lt;T, U&gt; Into&lt;U&gt; for T
where
    U: From&lt;T&gt;,
{
    fn into(self) -&gt; U {
        U::from(self)
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>The reason both traits exist is because it allows us to write trait bounds on generic types slightly differently:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn function&lt;T&gt;(t: T)
where
    // these bounds are equivalent
    T: From&lt;i32&gt;,
    i32: Into&lt;T&gt;
{
    // these examples are equivalent
    let example: T = T::from(0);
    let example: T = 0.into();
}
<span class="boring">}
</span></code></pre></pre>
<p>There are no hard rules about when to use one or the other, so go with whatever makes the most sense for each situation. Now let's look at some example impls on <code>Point</code>:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct Point {
    x: i32,
    y: i32,
}

impl From&lt;(i32, i32)&gt; for Point {
    fn from((x, y): (i32, i32)) -&gt; Self {
        Point { x, y }
    }
}

impl From&lt;[i32; 2]&gt; for Point {
    fn from([x, y]: [i32; 2]) -&gt; Self {
        Point { x, y }
    }
}

fn example() {
    // using From
    let origin = Point::from((0, 0));
    let origin = Point::from([0, 0]);

    // using Into
    let origin: Point = (0, 0).into();
    let origin: Point = [0, 0].into();
}
<span class="boring">}
</span></code></pre></pre>
<p>The impl is not symmetric, so if we'd like to convert <code>Point</code>s into tuples and arrays we have to explicitly add those as well:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct Point {
    x: i32,
    y: i32,
}

impl From&lt;(i32, i32)&gt; for Point {
    fn from((x, y): (i32, i32)) -&gt; Self {
        Point { x, y }
    }
}

impl From&lt;Point&gt; for (i32, i32) {
    fn from(Point { x, y }: Point) -&gt; Self {
        (x, y)
    }
}

impl From&lt;[i32; 2]&gt; for Point {
    fn from([x, y]: [i32; 2]) -&gt; Self {
        Point { x, y }
    }
}

impl From&lt;Point&gt; for [i32; 2] {
    fn from(Point { x, y }: Point) -&gt; Self {
        [x, y]
    }
}

fn example() {
    // from (i32, i32) into Point
    let point = Point::from((0, 0));
    let point: Point = (0, 0).into();

    // from Point into (i32, i32)
    let tuple = &lt;(i32, i32)&gt;::from(point);
    let tuple: (i32, i32) = point.into();

    // from [i32; 2] into Point
    let point = Point::from([0, 0]);
    let point: Point = [0, 0].into();

    // from Point into [i32; 2]
    let array = &lt;[i32; 2]&gt;::from(point);
    let array: [i32; 2] = point.into();
}
<span class="boring">}
</span></code></pre></pre>
<p>A popular use of <code>From&lt;T&gt;</code> is to trim down boilerplate code. Let's say we add a <code>Triangle</code> type to our program which contains three <code>Point</code>s, here's some of the many ways we can construct it:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct Point {
    x: i32,
    y: i32,
}

impl Point {
    fn new(x: i32, y: i32) -&gt; Point {
        Point { x, y }
    }
}

impl From&lt;(i32, i32)&gt; for Point {
    fn from((x, y): (i32, i32)) -&gt; Point {
        Point { x, y }
    }
}

struct Triangle {
    p1: Point,
    p2: Point,
    p3: Point,
}

impl Triangle {
    fn new(p1: Point, p2: Point, p3: Point) -&gt; Triangle {
        Triangle { p1, p2, p3 }
    }
}

impl&lt;P&gt; From&lt;[P; 3]&gt; for Triangle
where
    P: Into&lt;Point&gt;
{
    fn from([p1, p2, p3]: [P; 3]) -&gt; Triangle {
        Triangle {
            p1: p1.into(),
            p2: p2.into(),
            p3: p3.into(),
        }
    }
}

fn example() {
    // manual construction
    let triangle = Triangle {
        p1: Point {
            x: 0,
            y: 0,
        },
        p2: Point {
            x: 1,
            y: 1,
        },
        p3: Point {
            x: 2,
            y: 2,
        },
    };

    // using Point::new
    let triangle = Triangle {
        p1: Point::new(0, 0),
        p2: Point::new(1, 1),
        p3: Point::new(2, 2),
    };

    // using From&lt;(i32, i32)&gt; for Point
    let triangle = Triangle {
        p1: (0, 0).into(),
        p2: (1, 1).into(),
        p3: (2, 2).into(),
    };

    // using Triangle::new + From&lt;(i32, i32)&gt; for Point
    let triangle = Triangle::new(
        (0, 0).into(),
        (1, 1).into(),
        (2, 2).into(),
    );

    // using From&lt;[Into&lt;Point&gt;; 3]&gt; for Triangle
    let triangle: Triangle = [
        (0, 0),
        (1, 1),
        (2, 2),
    ].into();
}
<span class="boring">}
</span></code></pre></pre>
<p>There are no rules for when, how, or why we should impl <code>From&lt;T&gt;</code> for our types so it's up to us to use our best judgement for every situation.</p>
<p>One popular use of <code>Into&lt;T&gt;</code> is to make functions which need owned values generic over whether they take owned or borrowed values:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct Person {
    name: String,
}

impl Person {
    // accepts:
    // - String
    fn new1(name: String) -&gt; Person {
        Person { name }
    }

    // accepts:
    // - String
    // - &amp;String
    // - &amp;str
    // - Box&lt;str&gt;
    // - Cow&lt;'_, str&gt;
    // - char
    // since all of the above types can be converted into String
    fn new2&lt;N: Into&lt;String&gt;&gt;(name: N) -&gt; Person {
        Person { name: name.into() }
    }
}
<span class="boring">}
</span></code></pre></pre>
<h2 id="error-handling"><a class="header" href="#error-handling">Error Handling</a></h2>
<p>The best time to talk about error handling and the <code>Error</code> trait is after going over <code>Display</code>, <code>Debug</code>, <code>Any</code>, and <code>From</code> but before getting to <code>TryFrom</code> hence why the <strong>Error Handling</strong> section awkwardly bisects the <strong>Conversion Traits</strong> section.</p>
<h3 id="error"><a class="header" href="#error">Error</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#default-impls">Default Impls</a></li>
<li><a href="#generic-blanket-impls">Generic Blanket Impls</a></li>
<li><a href="#subtraits--supertraits">Subtraits &amp; Supertraits</a></li>
<li><a href="#trait-objects">Trait Objects</a></li>
<li><a href="#display--tostring">Display &amp; ToString</a></li>
<li><a href="#debug">Debug</a></li>
<li><a href="#any">Any</a></li>
<li><a href="#from--into">From &amp; Into</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Error: Debug + Display {
    // provided default impls
    fn source(&amp;self) -&gt; Option&lt;&amp;(dyn Error + 'static)&gt;;
    fn backtrace(&amp;self) -&gt; Option&lt;&amp;Backtrace&gt;;
    fn description(&amp;self) -&gt; &amp;str;
    fn cause(&amp;self) -&gt; Option&lt;&amp;dyn Error&gt;;
}
<span class="boring">}
</span></code></pre></pre>
<p>In Rust errors are returned, not thrown. Let's look at some examples.</p>
<p>Since dividing integer types by zero panics if we wanted to make our program safer and more explicit we could impl a <code>safe_div</code> function which returns a <code>Result</code> instead like this:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::fmt;
use std::error;

#[derive(Debug, PartialEq)]
struct DivByZero;

impl fmt::Display for DivByZero {
    fn fmt(&amp;self, f: &amp;mut fmt::Formatter&lt;'_&gt;) -&gt; fmt::Result {
        write!(f, &quot;division by zero error&quot;)
    }
}

impl error::Error for DivByZero {}

fn safe_div(numerator: i32, denominator: i32) -&gt; Result&lt;i32, DivByZero&gt; {
    if denominator == 0 {
        return Err(DivByZero);
    }
    Ok(numerator / denominator)
}

#[test] // ✅
fn test_safe_div() {
    assert_eq!(safe_div(8, 2), Ok(4));
    assert_eq!(safe_div(5, 0), Err(DivByZero));
}
<span class="boring">}
</span></code></pre></pre>
<p>Since errors are returned and not thrown they must be explicitly handled, and if the current function cannot handle an error it should propagate it up to the caller. The most idiomatic way to propagate errors is to use the <code>?</code> operator, which is just syntax sugar for the now deprecated <code>try!</code> macro which simply does this:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>macro_rules! try {
    ($expr:expr) =&gt; {
        match $expr {
            // if Ok just unwrap the value
            Ok(val) =&gt; val,
            // if Err map the err value using From and return
            Err(err) =&gt; {
                return Err(From::from(err));
            }
        }
    };
}
<span class="boring">}
</span></code></pre></pre>
<p>If we wanted to write a function which reads a file into a <code>String</code> we could write it like this, propagating the <code>io::Error</code>s using <code>?</code> everywhere they can appear:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::io::Read;
use std::path::Path;
use std::io;
use std::fs::File;

fn read_file_to_string(path: &amp;Path) -&gt; Result&lt;String, io::Error&gt; {
    let mut file = File::open(path)?; // ⬆️ io::Error
    let mut contents = String::new();
    file.read_to_string(&amp;mut contents)?; // ⬆️ io::Error
    Ok(contents)
}
<span class="boring">}
</span></code></pre></pre>
<p>But let's say the file we're reading is actually a list of numbers and we want to sum them together, we'd update our function like this:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::io::Read;
use std::path::Path;
use std::io;
use std::fs::File;

fn sum_file(path: &amp;Path) -&gt; Result&lt;i32, /* What to put here? */&gt; {
    let mut file = File::open(path)?; // ⬆️ io::Error
    let mut contents = String::new();
    file.read_to_string(&amp;mut contents)?; // ⬆️ io::Error
    let mut sum = 0;
    for line in contents.lines() {
        sum += line.parse::&lt;i32&gt;()?; // ⬆️ ParseIntError
    }
    Ok(sum)
}
<span class="boring">}
</span></code></pre></pre>
<p>But what's the error type of our <code>Result</code> now? It can return either an <code>io::Error</code> or a <code>ParseIntError</code>. We're going to look at three approaches for solving this problem, starting with the most quick &amp; dirty way and finishing with the most robust way.</p>
<p>The first approach is recognizing that all types which impl <code>Error</code> also impl <code>Display</code> so we can map all the errors to <code>String</code>s and use <code>String</code> as our error type:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::fs::File;
use std::io;
use std::io::Read;
use std::path::Path;

fn sum_file(path: &amp;Path) -&gt; Result&lt;i32, String&gt; {
    let mut file = File::open(path)
        .map_err(|e| e.to_string())?; // ⬆️ io::Error -&gt; String
    let mut contents = String::new();
    file.read_to_string(&amp;mut contents)
        .map_err(|e| e.to_string())?; // ⬆️ io::Error -&gt; String
    let mut sum = 0;
    for line in contents.lines() {
        sum += line.parse::&lt;i32&gt;()
            .map_err(|e| e.to_string())?; // ⬆️ ParseIntError -&gt; String
    }
    Ok(sum)
}
<span class="boring">}
</span></code></pre></pre>
<p>The obvious downside of stringifying every error is that we throw away type information which makes it harder for the caller to handle the errors.</p>
<p>One nonobvious upside to the above approach is we can customize the strings to provide more context-specific information. For example, <code>ParseIntError</code> usually stringifies to <code>&quot;invalid digit found in string&quot;</code> which is very vague and doesn't mention what the invalid string is or what integer type it was trying to parse into. If we were debugging this problem that error message would almost be useless. However we can make it significantly better by providing all the context relevant information ourselves:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>sum += line.parse::&lt;i32&gt;()
    .map_err(|_| format!(&quot;failed to parse {} into i32&quot;, line))?;
<span class="boring">}
</span></code></pre></pre>
<p>The second approach takes advantage of this generic blanket impl from the standard library:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>impl&lt;E: error::Error&gt; From&lt;E&gt; for Box&lt;dyn error::Error&gt;;
<span class="boring">}
</span></code></pre></pre>
<p>Which means that any <code>Error</code> type can be implicitly converted into a <code>Box&lt;dyn error::Error&gt;</code> by the <code>?</code> operator, so we can set to error type to <code>Box&lt;dyn error::Error&gt;</code> in the <code>Result</code> return type of any function which produces errors and the <code>?</code> operator will do the rest of the work for us:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::error;

fn sum_file(path: &amp;Path) -&gt; Result&lt;i32, Box&lt;dyn error::Error&gt;&gt; {
    let mut file = File::open(path)?; // ⬆️ io::Error -&gt; Box&lt;dyn error::Error&gt;
    let mut contents = String::new();
    file.read_to_string(&amp;mut contents)?; // ⬆️ io::Error -&gt; Box&lt;dyn error::Error&gt;
    let mut sum = 0;
    for line in contents.lines() {
        sum += line.parse::&lt;i32&gt;()?; // ⬆️ ParseIntError -&gt; Box&lt;dyn error::Error&gt;
    }
    Ok(sum)
}
<span class="boring">}
</span></code></pre></pre>
<p>While being more concise, this seems to suffer from the same downside of the previous approach by throwing away type information. This is mostly true, but if the caller is aware of the impl details of our function they can still handle the different errors types using the <code>downcast_ref()</code> method on <code>error::Error</code> which works the same as it does on <code>dyn Any</code> types:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn handle_sum_file_errors(path: &amp;Path) {
    match sum_file(path) {
        Ok(sum) =&gt; println!(&quot;the sum is {}&quot;, sum),
        Err(err) =&gt; {
            if let Some(e) = err.downcast_ref::&lt;io::Error&gt;() {
                // handle io::Error
            } else if let Some(e) = err.downcast_ref::&lt;ParseIntError&gt;() {
                // handle ParseIntError
            } else {
                // we know sum_file can only return one of the
                // above errors so this branch is unreachable
                unreachable!();
            }
        }
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>The third approach, which is the most robust and type-safe way to aggregate these different errors would be to build our own custom error type using an enum:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::num::ParseIntError;
use std::fs::File;
use std::io;
use std::io::Read;
use std::path::Path;
use std::error;
use std::fmt;

#[derive(Debug)]
enum SumFileError {
    Io(io::Error),
    Parse(ParseIntError),
}

impl From&lt;io::Error&gt; for SumFileError {
    fn from(err: io::Error) -&gt; Self {
        SumFileError::Io(err)
    }
}

impl From&lt;ParseIntError&gt; for SumFileError {
    fn from(err: ParseIntError) -&gt; Self {
        SumFileError::Parse(err)
    }
}

impl fmt::Display for SumFileError {
    fn fmt(&amp;self, f: &amp;mut fmt::Formatter&lt;'_&gt;) -&gt; fmt::Result {
        match self {
            SumFileError::Io(err) =&gt; write!(f, &quot;sum file error: {}&quot;, err),
            SumFileError::Parse(err) =&gt; write!(f, &quot;sum file error: {}&quot;, err),
        }
    }
}

impl error::Error for SumFileError {
    // the default impl for this method always returns None
    // but we can now override it to make it way more useful!
    fn source(&amp;self) -&gt; Option&lt;&amp;(dyn error::Error + 'static)&gt; {
        Some(match self {
            SumFileError::Io(err) =&gt; err,
            SumFileError::Parse(err) =&gt; err,
        })
    }
}

fn sum_file(path: &amp;Path) -&gt; Result&lt;i32, SumFileError&gt; {
    let mut file = File::open(path)?; // ⬆️ io::Error -&gt; SumFileError
    let mut contents = String::new();
    file.read_to_string(&amp;mut contents)?; // ⬆️ io::Error -&gt; SumFileError
    let mut sum = 0;
    for line in contents.lines() {
        sum += line.parse::&lt;i32&gt;()?; // ⬆️ ParseIntError -&gt; SumFileError
    }
    Ok(sum)
}

fn handle_sum_file_errors(path: &amp;Path) {
    match sum_file(path) {
        Ok(sum) =&gt; println!(&quot;the sum is {}&quot;, sum),
        Err(SumFileError::Io(err)) =&gt; {
            // handle io::Error
        },
        Err(SumFileError::Parse(err)) =&gt; {
            // handle ParseIntError
        },
    }
}
<span class="boring">}
</span></code></pre></pre>
<h2 id="conversion-traits-continued"><a class="header" href="#conversion-traits-continued">Conversion Traits Continued</a></h2>
<h3 id="tryfrom--tryinto"><a class="header" href="#tryfrom--tryinto">TryFrom &amp; TryInto</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#functions">Functions</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#associated-types">Associated Types</a></li>
<li><a href="#generic-parameters">Generic Parameters</a></li>
<li><a href="#generic-types-vs-associated-types">Generic Types vs Associated Types</a></li>
<li><a href="#generic-blanket-impls">Generic Blanket Impls</a></li>
<li><a href="#from--into">From &amp; Into</a></li>
<li><a href="#error">Error</a></li>
</ul>
<p><code>TryFrom</code> and <code>TryInto</code> are the fallible versions of <code>From</code> and <code>Into</code>.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait TryFrom&lt;T&gt; {
    type Error;
    fn try_from(value: T) -&gt; Result&lt;Self, Self::Error&gt;;
}

trait TryInto&lt;T&gt; {
    type Error;
    fn try_into(self) -&gt; Result&lt;T, Self::Error&gt;;
}
<span class="boring">}
</span></code></pre></pre>
<p>Similarly to <code>Into</code> we cannot impl <code>TryInto</code> because its impl is provided by this generic blanket impl:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>impl&lt;T, U&gt; TryInto&lt;U&gt; for T
where
    U: TryFrom&lt;T&gt;,
{
    type Error = U::Error;

    fn try_into(self) -&gt; Result&lt;U, U::Error&gt; {
        U::try_from(self)
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>Let's say that in the context of our program it doesn't make sense for <code>Point</code>s to have <code>x</code> and <code>y</code> values that are less than <code>-1000</code> or greater than <code>1000</code>. This is how we'd rewrite our earlier <code>From</code> impls using <code>TryFrom</code> to signal to the users of our type that this conversion can now fail:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::convert::TryFrom;
use std::error;
use std::fmt;

struct Point {
    x: i32,
    y: i32,
}

#[derive(Debug)]
struct OutOfBounds;

impl fmt::Display for OutOfBounds {
    fn fmt(&amp;self, f: &amp;mut fmt::Formatter&lt;'_&gt;) -&gt; fmt::Result {
        write!(f, &quot;out of bounds&quot;)
    }
}

impl error::Error for OutOfBounds {}

// now fallible
impl TryFrom&lt;(i32, i32)&gt; for Point {
    type Error = OutOfBounds;
    fn try_from((x, y): (i32, i32)) -&gt; Result&lt;Point, OutOfBounds&gt; {
        if x.abs() &gt; 1000 || y.abs() &gt; 1000 {
            return Err(OutOfBounds);
        }
        Ok(Point { x, y })
    }
}

// still infallible
impl From&lt;Point&gt; for (i32, i32) {
    fn from(Point { x, y }: Point) -&gt; Self {
        (x, y)
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>And here's the refactored <code>TryFrom&lt;[TryInto&lt;Point&gt;; 3]&gt;</code> impl for <code>Triangle</code>:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::convert::{TryFrom, TryInto};
use std::error;
use std::fmt;

struct Point {
    x: i32,
    y: i32,
}

#[derive(Debug)]
struct OutOfBounds;

impl fmt::Display for OutOfBounds {
    fn fmt(&amp;self, f: &amp;mut fmt::Formatter&lt;'_&gt;) -&gt; fmt::Result {
        write!(f, &quot;out of bounds&quot;)
    }
}

impl error::Error for OutOfBounds {}

impl TryFrom&lt;(i32, i32)&gt; for Point {
    type Error = OutOfBounds;
    fn try_from((x, y): (i32, i32)) -&gt; Result&lt;Self, Self::Error&gt; {
        if x.abs() &gt; 1000 || y.abs() &gt; 1000 {
            return Err(OutOfBounds);
        }
        Ok(Point { x, y })
    }
}

struct Triangle {
    p1: Point,
    p2: Point,
    p3: Point,
}

impl&lt;P&gt; TryFrom&lt;[P; 3]&gt; for Triangle
where
    P: TryInto&lt;Point&gt;,
{
    type Error = P::Error;
    fn try_from([p1, p2, p3]: [P; 3]) -&gt; Result&lt;Self, Self::Error&gt; {
        Ok(Triangle {
            p1: p1.try_into()?,
            p2: p2.try_into()?,
            p3: p3.try_into()?,
        })
    }
}

fn example() -&gt; Result&lt;Triangle, OutOfBounds&gt; {
    let t: Triangle = [(0, 0), (1, 1), (2, 2)].try_into()?;
    Ok(t)
}
<span class="boring">}
</span></code></pre></pre>
<h3 id="fromstr"><a class="header" href="#fromstr">FromStr</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#functions">Functions</a></li>
<li><a href="#associated-types">Associated Types</a></li>
<li><a href="#error">Error</a></li>
<li><a href="#tryfrom--tryinto">TryFrom &amp; TryInto</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait FromStr {
    type Err;
    fn from_str(s: &amp;str) -&gt; Result&lt;Self, Self::Err&gt;;
}
<span class="boring">}
</span></code></pre></pre>
<p><code>FromStr</code> types allow performing a fallible conversion from <code>&amp;str</code> into <code>Self</code>. The idiomatic way to use <code>FromStr</code> is to call the <code>.parse()</code> method on <code>&amp;str</code>s:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::str::FromStr;

fn example&lt;T: FromStr&gt;(s: &amp;'static str) {
    // these are all equivalent
    let t: Result&lt;T, _&gt; = FromStr::from_str(s);
    let t = T::from_str(s);
    let t: Result&lt;T, _&gt; = s.parse();
    let t = s.parse::&lt;T&gt;(); // most idiomatic
}
<span class="boring">}
</span></code></pre></pre>
<p>Example impl for <code>Point</code>:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::error;
use std::fmt;
use std::iter::Enumerate;
use std::num::ParseIntError;
use std::str::{Chars, FromStr};

#[derive(Debug, Eq, PartialEq)]
struct Point {
    x: i32,
    y: i32,
}

impl Point {
    fn new(x: i32, y: i32) -&gt; Self {
        Point { x, y }
    }
}

#[derive(Debug, PartialEq)]
struct ParsePointError;

impl fmt::Display for ParsePointError {
    fn fmt(&amp;self, f: &amp;mut fmt::Formatter&lt;'_&gt;) -&gt; fmt::Result {
        write!(f, &quot;failed to parse point&quot;)
    }
}

impl From&lt;ParseIntError&gt; for ParsePointError {
    fn from(_e: ParseIntError) -&gt; Self {
        ParsePointError
    }
}

impl error::Error for ParsePointError {}

impl FromStr for Point {
    type Err = ParsePointError;

    fn from_str(s: &amp;str) -&gt; Result&lt;Self, Self::Err&gt; {
        let is_num = |(_, c): &amp;(usize, char)| matches!(c, '0'..='9' | '-');
        let isnt_num = |t: &amp;(_, _)| !is_num(t);

        let get_num =
            |char_idxs: &amp;mut Enumerate&lt;Chars&lt;'_&gt;&gt;| -&gt; Result&lt;(usize, usize), ParsePointError&gt; {
                let (start, _) = char_idxs
                    .skip_while(isnt_num)
                    .next()
                    .ok_or(ParsePointError)?;
                let (end, _) = char_idxs
                    .skip_while(is_num)
                    .next()
                    .ok_or(ParsePointError)?;
                Ok((start, end))
            };

        let mut char_idxs = s.chars().enumerate();
        let (x_start, x_end) = get_num(&amp;mut char_idxs)?;
        let (y_start, y_end) = get_num(&amp;mut char_idxs)?;

        let x = s[x_start..x_end].parse::&lt;i32&gt;()?;
        let y = s[y_start..y_end].parse::&lt;i32&gt;()?;

        Ok(Point { x, y })
    }
}

#[test] // ✅
fn pos_x_y() {
    let p = &quot;(4, 5)&quot;.parse::&lt;Point&gt;();
    assert_eq!(p, Ok(Point::new(4, 5)));
}

#[test] // ✅
fn neg_x_y() {
    let p = &quot;(-6, -2)&quot;.parse::&lt;Point&gt;();
    assert_eq!(p, Ok(Point::new(-6, -2)));
}

#[test] // ✅
fn not_a_point() {
    let p = &quot;not a point&quot;.parse::&lt;Point&gt;();
    assert_eq!(p, Err(ParsePointError));
}
<span class="boring">}
</span></code></pre></pre>
<p><code>FromStr</code> has the same signature as <code>TryFrom&lt;&amp;str&gt;</code>. It doesn't matter which one we impl for a type first as long as we forward the impl to the other one. Here's a <code>TryFrom&lt;&amp;str&gt;</code> impl for <code>Point</code> assuming it already has a <code>FromStr</code> impl:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>impl TryFrom&lt;&amp;str&gt; for Point {
    type Error = &lt;Point as FromStr&gt;::Err;
    fn try_from(s: &amp;str) -&gt; Result&lt;Point, Self::Error&gt; {
        &lt;Point as FromStr&gt;::from_str(s)
    }
}
<span class="boring">}
</span></code></pre></pre>
<h3 id="asref--asmut"><a class="header" href="#asref--asmut">AsRef &amp; AsMut</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#sized">Sized</a></li>
<li><a href="#generic-parameters">Generic Parameters</a></li>
<li><a href="#sized">Sized</a></li>
<li><a href="#deref--derefmut">Deref &amp; DerefMut</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait AsRef&lt;T: ?Sized&gt; {
    fn as_ref(&amp;self) -&gt; &amp;T;
}

trait AsMut&lt;T: ?Sized&gt; {
    fn as_mut(&amp;mut self) -&gt; &amp;mut T;
}
<span class="boring">}
</span></code></pre></pre>
<p><code>AsRef</code> is for cheap reference to reference conversions. However, one of the most common ways it's used is to make functions generic over whether they take ownership or not:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// accepts:
//  - &amp;str
//  - &amp;String
fn takes_str(s: &amp;str) {
    // use &amp;str
}

// accepts:
//  - &amp;str
//  - &amp;String
//  - String
fn takes_asref_str&lt;S: AsRef&lt;str&gt;&gt;(s: S) {
    let s: &amp;str = s.as_ref();
    // use &amp;str
}

fn example(slice: &amp;str, borrow: &amp;String, owned: String) {
    takes_str(slice);
    takes_str(borrow);
    takes_str(owned); // ❌
    takes_asref_str(slice);
    takes_asref_str(borrow);
    takes_asref_str(owned); // ✅
}
<span class="boring">}
</span></code></pre></pre>
<p>The other most common use-case is returning a reference to inner private data wrapped by a type which protects some invariant. A good example from the standard library is <code>String</code> which is just a wrapper around <code>Vec&lt;u8&gt;</code>:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct String {
    vec: Vec&lt;u8&gt;,
}
<span class="boring">}
</span></code></pre></pre>
<p>This inner <code>Vec</code> cannot be made public because if it was people could mutate any byte and break the <code>String</code>'s valid UTF-8 encoding. However, it's safe to expose an immutable read-only reference to the inner byte array, hence this impl:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>impl AsRef&lt;[u8]&gt; for String;
<span class="boring">}
</span></code></pre></pre>
<p>Generally, it often only makes sense to impl <code>AsRef</code> for a type if it wraps some other type to either provide additional functionality around the inner type or protect some invariant on the inner type.</p>
<p>Let's examine a example of bad <code>AsRef</code> impls:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct User {
    name: String,
    age: u32,
}

impl AsRef&lt;String&gt; for User {
    fn as_ref(&amp;self) -&gt; &amp;String {
        &amp;self.name
    }
}

impl AsRef&lt;u32&gt; for User {
    fn as_ref(&amp;self) -&gt; &amp;u32 {
        &amp;self.age
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>This works and kinda makes sense at first, but quickly falls apart if we add more members to <code>User</code>:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct User {
    name: String,
    email: String,
    age: u32,
    height: u32,
}

impl AsRef&lt;String&gt; for User {
    fn as_ref(&amp;self) -&gt; &amp;String {
        // uh, do we return name or email here?
    }
}

impl AsRef&lt;u32&gt; for User {
    fn as_ref(&amp;self) -&gt; &amp;u32 {
        // uh, do we return age or height here?
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>A <code>User</code> is composed of <code>String</code>s and <code>u32</code>s but it's not really the same thing as a <code>String</code> or a <code>u32</code>. Even if we had much more specific types:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct User {
    name: Name,
    email: Email,
    age: Age,
    height: Height,
}
<span class="boring">}
</span></code></pre></pre>
<p>It wouldn't make much sense to impl <code>AsRef</code> for any of those because <code>AsRef</code> is for cheap reference to reference conversions between semantically equivalent things, and <code>Name</code>, <code>Email</code>, <code>Age</code>, and <code>Height</code> by themselves are not the same thing as a <code>User</code>.</p>
<p>A good example where we would impl <code>AsRef</code> would be if we introduced a new type <code>Moderator</code> that just wrapped a <code>User</code> and added some moderation specific privileges:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct User {
    name: String,
    age: u32,
}

// unfortunately the standard library cannot provide
// a generic blanket impl to save us from this boilerplate
impl AsRef&lt;User&gt; for User {
    fn as_ref(&amp;self) -&gt; &amp;User {
        self
    }
}

enum Privilege {
    BanUsers,
    EditPosts,
    DeletePosts,
}

// although Moderators have some special
// privileges they are still regular Users
// and should be able to do all the same stuff
struct Moderator {
    user: User,
    privileges: Vec&lt;Privilege&gt;
}

impl AsRef&lt;Moderator&gt; for Moderator {
    fn as_ref(&amp;self) -&gt; &amp;Moderator {
        self
    }
}

impl AsRef&lt;User&gt; for Moderator {
    fn as_ref(&amp;self) -&gt; &amp;User {
        &amp;self.user
    }
}

// this should be callable with Users
// and Moderators (who are also Users)
fn create_post&lt;U: AsRef&lt;User&gt;&gt;(u: U) {
    let user = u.as_ref();
    // etc
}

fn example(user: User, moderator: Moderator) {
    create_post(&amp;user);
    create_post(&amp;moderator); // ✅
}
<span class="boring">}
</span></code></pre></pre>
<p>This works because <code>Moderator</code>s are just <code>User</code>s. Here's the example from the <code>Deref</code> section except using <code>AsRef</code> instead:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::convert::AsRef;

struct Human {
    health_points: u32,
}

impl AsRef&lt;Human&gt; for Human {
    fn as_ref(&amp;self) -&gt; &amp;Human {
        self
    }
}

enum Weapon {
    Spear,
    Axe,
    Sword,
}

// a Soldier is just a Human with a Weapon
struct Soldier {
    human: Human,
    weapon: Weapon,
}

impl AsRef&lt;Soldier&gt; for Soldier {
    fn as_ref(&amp;self) -&gt; &amp;Soldier {
        self
    }
}

impl AsRef&lt;Human&gt; for Soldier {
    fn as_ref(&amp;self) -&gt; &amp;Human {
        &amp;self.human
    }
}

enum Mount {
    Horse,
    Donkey,
    Cow,
}

// a Knight is just a Soldier with a Mount
struct Knight {
    soldier: Soldier,
    mount: Mount,
}

impl AsRef&lt;Knight&gt; for Knight {
    fn as_ref(&amp;self) -&gt; &amp;Knight {
        self
    }
}

impl AsRef&lt;Soldier&gt; for Knight {
    fn as_ref(&amp;self) -&gt; &amp;Soldier {
        &amp;self.soldier
    }
}

impl AsRef&lt;Human&gt; for Knight {
    fn as_ref(&amp;self) -&gt; &amp;Human {
        &amp;self.soldier.human
    }
}

enum Spell {
    MagicMissile,
    FireBolt,
    ThornWhip,
}

// a Mage is just a Human who can cast Spells
struct Mage {
    human: Human,
    spells: Vec&lt;Spell&gt;,
}

impl AsRef&lt;Mage&gt; for Mage {
    fn as_ref(&amp;self) -&gt; &amp;Mage {
        self
    }
}

impl AsRef&lt;Human&gt; for Mage {
    fn as_ref(&amp;self) -&gt; &amp;Human {
        &amp;self.human
    }
}

enum Staff {
    Wooden,
    Metallic,
    Plastic,
}

// a Wizard is just a Mage with a Staff
struct Wizard {
    mage: Mage,
    staff: Staff,
}

impl AsRef&lt;Wizard&gt; for Wizard {
    fn as_ref(&amp;self) -&gt; &amp;Wizard {
        self
    }
}

impl AsRef&lt;Mage&gt; for Wizard {
    fn as_ref(&amp;self) -&gt; &amp;Mage {
        &amp;self.mage
    }
}

impl AsRef&lt;Human&gt; for Wizard {
    fn as_ref(&amp;self) -&gt; &amp;Human {
        &amp;self.mage.human
    }
}

fn borrows_human&lt;H: AsRef&lt;Human&gt;&gt;(human: H) {}
fn borrows_soldier&lt;S: AsRef&lt;Soldier&gt;&gt;(soldier: S) {}
fn borrows_knight&lt;K: AsRef&lt;Knight&gt;&gt;(knight: K) {}
fn borrows_mage&lt;M: AsRef&lt;Mage&gt;&gt;(mage: M) {}
fn borrows_wizard&lt;W: AsRef&lt;Wizard&gt;&gt;(wizard: W) {}

fn example(human: Human, soldier: Soldier, knight: Knight, mage: Mage, wizard: Wizard) {
    // all types can be used as Humans
    borrows_human(&amp;human);
    borrows_human(&amp;soldier);
    borrows_human(&amp;knight);
    borrows_human(&amp;mage);
    borrows_human(&amp;wizard);
    // Knights can be used as Soldiers
    borrows_soldier(&amp;soldier);
    borrows_soldier(&amp;knight);
    // Wizards can be used as Mages
    borrows_mage(&amp;mage);
    borrows_mage(&amp;wizard);
    // Knights &amp; Wizards passed as themselves
    borrows_knight(&amp;knight);
    borrows_wizard(&amp;wizard);
}
<span class="boring">}
</span></code></pre></pre>
<p><code>Deref</code> didn't work in the prior version of the example above because deref coercion is an implicit conversion between types which leaves room for people to mistakenly formulate the wrong ideas and expectations for how it will behave. <code>AsRef</code> works above because it makes the conversion between types explicit and there's no room leftover to develop any wrong ideas or expectations.</p>
<h3 id="borrow--borrowmut"><a class="header" href="#borrow--borrowmut">Borrow &amp; BorrowMut</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#generic-parameters">Generic Parameters</a></li>
<li><a href="#subtraits--supertraits">Subtraits &amp; Supertraits</a></li>
<li><a href="#sized">Sized</a></li>
<li><a href="#asref--asmut">AsRef &amp; AsMut</a></li>
<li><a href="#partialeq--eq">PartialEq &amp; Eq</a></li>
<li><a href="#hash">Hash</a></li>
<li><a href="#partialord--ord">PartialOrd &amp; Ord</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Borrow&lt;Borrowed&gt; 
where
    Borrowed: ?Sized, 
{
    fn borrow(&amp;self) -&gt; &amp;Borrowed;
}

trait BorrowMut&lt;Borrowed&gt;: Borrow&lt;Borrowed&gt; 
where
    Borrowed: ?Sized, 
{
    fn borrow_mut(&amp;mut self) -&gt; &amp;mut Borrowed;
}
<span class="boring">}
</span></code></pre></pre>
<p>These traits were invented to solve the very specific problem of looking up <code>String</code> keys in <code>HashSet</code>s, <code>HashMap</code>s, <code>BTreeSet</code>s, and <code>BTreeMap</code>s using <code>&amp;str</code> values.</p>
<p>We can view <code>Borrow&lt;T&gt;</code> and <code>BorrowMut&lt;T&gt;</code> as stricter versions of <code>AsRef&lt;T&gt;</code> and <code>AsMut&lt;T&gt;</code>, where the returned reference <code>&amp;T</code> has equivalent <code>Eq</code>, <code>Hash</code>, and <code>Ord</code> impls to <code>Self</code>. This is more easily explained with a commented example:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::borrow::Borrow;
use std::hash::Hasher;
use std::collections::hash_map::DefaultHasher;
use std::hash::Hash;

fn get_hash&lt;T: Hash&gt;(t: T) -&gt; u64 {
    let mut hasher = DefaultHasher::new();
    t.hash(&amp;mut hasher);
    hasher.finish()
}

fn asref_example&lt;Owned, Ref&gt;(owned1: Owned, owned2: Owned)
where
    Owned: Eq + Ord + Hash + AsRef&lt;Ref&gt;,
    Ref: Eq + Ord + Hash
{
    let ref1: &amp;Ref = owned1.as_ref();
    let ref2: &amp;Ref = owned2.as_ref();
    
    // refs aren't required to be equal if owned types are equal
    assert_eq!(owned1 == owned2, ref1 == ref2); // ❌
    
    let owned1_hash = get_hash(&amp;owned1);
    let owned2_hash = get_hash(&amp;owned2);
    let ref1_hash = get_hash(&amp;ref1);
    let ref2_hash = get_hash(&amp;ref2);
    
    // ref hashes aren't required to be equal if owned type hashes are equal
    assert_eq!(owned1_hash == owned2_hash, ref1_hash == ref2_hash); // ❌
    
    // ref comparisons aren't required to match owned type comparisons
    assert_eq!(owned1.cmp(&amp;owned2), ref1.cmp(&amp;ref2)); // ❌
}

fn borrow_example&lt;Owned, Borrowed&gt;(owned1: Owned, owned2: Owned)
where
    Owned: Eq + Ord + Hash + Borrow&lt;Borrowed&gt;,
    Borrowed: Eq + Ord + Hash
{
    let borrow1: &amp;Borrowed = owned1.borrow();
    let borrow2: &amp;Borrowed = owned2.borrow();
    
    // borrows are required to be equal if owned types are equal
    assert_eq!(owned1 == owned2, borrow1 == borrow2); // ✅
    
    let owned1_hash = get_hash(&amp;owned1);
    let owned2_hash = get_hash(&amp;owned2);
    let borrow1_hash = get_hash(&amp;borrow1);
    let borrow2_hash = get_hash(&amp;borrow2);
    
    // borrow hashes are required to be equal if owned type hashes are equal
    assert_eq!(owned1_hash == owned2_hash, borrow1_hash == borrow2_hash); // ✅
    
    // borrow comparisons are required to match owned type comparisons
    assert_eq!(owned1.cmp(&amp;owned2), borrow1.cmp(&amp;borrow2)); // ✅
}
<span class="boring">}
</span></code></pre></pre>
<p>It's good to be aware of these traits and understand why they exist since it helps demystify some of the methods on <code>HashSet</code>, <code>HashMap</code>, <code>BTreeSet</code>, and <code>BTreeMap</code> but it's very rare that we would ever need to impl these traits for any of our types because it's very rare that we would ever need create a pair of types where one is the &quot;borrowed&quot; version of the other in the first place. If we have some <code>T</code> then <code>&amp;T</code> will get the job done 99.99% of the time, and <code>T: Borrow&lt;T&gt;</code> is already implemented for all <code>T</code> because of a generic blanket impl, so we don't need to manually impl it and we don't need to create some <code>U</code> such that <code>T: Borrow&lt;U&gt;</code>.</p>
<h3 id="toowned"><a class="header" href="#toowned">ToOwned</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#default-impls">Default Impls</a></li>
<li><a href="#clone">Clone</a></li>
<li><a href="#borrow--borrowmut">Borrow &amp; BorrowMut</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait ToOwned {
    type Owned: Borrow&lt;Self&gt;;
    fn to_owned(&amp;self) -&gt; Self::Owned;
    
    // provided default impls
    fn clone_into(&amp;self, target: &amp;mut Self::Owned);
}
<span class="boring">}
</span></code></pre></pre>
<p><code>ToOwned</code> is a more generic version of <code>Clone</code>. <code>Clone</code> allows us to take a <code>&amp;T</code> and turn it into an <code>T</code> but <code>ToOwned</code> allows us to take a <code>&amp;Borrowed</code> and turn it into a <code>Owned</code> where <code>Owned: Borrow&lt;Borrowed&gt;</code>.</p>
<p>In other words, we can't &quot;clone&quot; a <code>&amp;str</code> into a <code>String</code>, or a <code>&amp;Path</code> into a <code>PathBuf</code>, or an <code>&amp;OsStr</code> into an <code>OsString</code>, since the <code>clone</code> method signature doesn't support this kind of cross-type cloning, and that's what <code>ToOwned</code> was made for.</p>
<p>For similar reasons as <code>Borrow</code> and <code>BorrowMut</code>, it's good to be aware of this trait and understand why it exists but it's very rare we'll ever need to impl it for any of our types.</p>
<h2 id="iteration-traits"><a class="header" href="#iteration-traits">Iteration Traits</a></h2>
<h3 id="iterator"><a class="header" href="#iterator">Iterator</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#associated-types">Associated Types</a></li>
<li><a href="#default-impls">Default Impls</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Iterator {
    type Item;
    fn next(&amp;mut self) -&gt; Option&lt;Self::Item&gt;;

    // provided default impls
    fn size_hint(&amp;self) -&gt; (usize, Option&lt;usize&gt;);
    fn count(self) -&gt; usize;
    fn last(self) -&gt; Option&lt;Self::Item&gt;;
    fn advance_by(&amp;mut self, n: usize) -&gt; Result&lt;(), usize&gt;;
    fn nth(&amp;mut self, n: usize) -&gt; Option&lt;Self::Item&gt;;
    fn step_by(self, step: usize) -&gt; StepBy&lt;Self&gt;;
    fn chain&lt;U&gt;(
        self, 
        other: U
    ) -&gt; Chain&lt;Self, &lt;U as IntoIterator&gt;::IntoIter&gt;
    where
        U: IntoIterator&lt;Item = Self::Item&gt;;
    fn zip&lt;U&gt;(self, other: U) -&gt; Zip&lt;Self, &lt;U as IntoIterator&gt;::IntoIter&gt;
    where
        U: IntoIterator;
    fn map&lt;B, F&gt;(self, f: F) -&gt; Map&lt;Self, F&gt;
    where
        F: FnMut(Self::Item) -&gt; B;
    fn for_each&lt;F&gt;(self, f: F)
    where
        F: FnMut(Self::Item);
    fn filter&lt;P&gt;(self, predicate: P) -&gt; Filter&lt;Self, P&gt;
    where
        P: FnMut(&amp;Self::Item) -&gt; bool;
    fn filter_map&lt;B, F&gt;(self, f: F) -&gt; FilterMap&lt;Self, F&gt;
    where
        F: FnMut(Self::Item) -&gt; Option&lt;B&gt;;
    fn enumerate(self) -&gt; Enumerate&lt;Self&gt;;
    fn peekable(self) -&gt; Peekable&lt;Self&gt;;
    fn skip_while&lt;P&gt;(self, predicate: P) -&gt; SkipWhile&lt;Self, P&gt;
    where
        P: FnMut(&amp;Self::Item) -&gt; bool;
    fn take_while&lt;P&gt;(self, predicate: P) -&gt; TakeWhile&lt;Self, P&gt;
    where
        P: FnMut(&amp;Self::Item) -&gt; bool;
    fn map_while&lt;B, P&gt;(self, predicate: P) -&gt; MapWhile&lt;Self, P&gt;
    where
        P: FnMut(Self::Item) -&gt; Option&lt;B&gt;;
    fn skip(self, n: usize) -&gt; Skip&lt;Self&gt;;
    fn take(self, n: usize) -&gt; Take&lt;Self&gt;;
    fn scan&lt;St, B, F&gt;(self, initial_state: St, f: F) -&gt; Scan&lt;Self, St, F&gt;
    where
        F: FnMut(&amp;mut St, Self::Item) -&gt; Option&lt;B&gt;;
    fn flat_map&lt;U, F&gt;(self, f: F) -&gt; FlatMap&lt;Self, U, F&gt;
    where
        F: FnMut(Self::Item) -&gt; U,
        U: IntoIterator;
    fn flatten(self) -&gt; Flatten&lt;Self&gt;
    where
        Self::Item: IntoIterator;
    fn fuse(self) -&gt; Fuse&lt;Self&gt;;
    fn inspect&lt;F&gt;(self, f: F) -&gt; Inspect&lt;Self, F&gt;
    where
        F: FnMut(&amp;Self::Item);
    fn by_ref(&amp;mut self) -&gt; &amp;mut Self;
    fn collect&lt;B&gt;(self) -&gt; B
    where
        B: FromIterator&lt;Self::Item&gt;;
    fn partition&lt;B, F&gt;(self, f: F) -&gt; (B, B)
    where
        F: FnMut(&amp;Self::Item) -&gt; bool,
        B: Default + Extend&lt;Self::Item&gt;;
    fn partition_in_place&lt;'a, T, P&gt;(self, predicate: P) -&gt; usize
    where
        Self: DoubleEndedIterator&lt;Item = &amp;'a mut T&gt;,
        T: 'a,
        P: FnMut(&amp;T) -&gt; bool;
    fn is_partitioned&lt;P&gt;(self, predicate: P) -&gt; bool
    where
        P: FnMut(Self::Item) -&gt; bool;
    fn try_fold&lt;B, F, R&gt;(&amp;mut self, init: B, f: F) -&gt; R
    where
        F: FnMut(B, Self::Item) -&gt; R,
        R: Try&lt;Ok = B&gt;;
    fn try_for_each&lt;F, R&gt;(&amp;mut self, f: F) -&gt; R
    where
        F: FnMut(Self::Item) -&gt; R,
        R: Try&lt;Ok = ()&gt;;
    fn fold&lt;B, F&gt;(self, init: B, f: F) -&gt; B
    where
        F: FnMut(B, Self::Item) -&gt; B;
    fn fold_first&lt;F&gt;(self, f: F) -&gt; Option&lt;Self::Item&gt;
    where
        F: FnMut(Self::Item, Self::Item) -&gt; Self::Item;
    fn all&lt;F&gt;(&amp;mut self, f: F) -&gt; bool
    where
        F: FnMut(Self::Item) -&gt; bool;
    fn any&lt;F&gt;(&amp;mut self, f: F) -&gt; bool
    where
        F: FnMut(Self::Item) -&gt; bool;
    fn find&lt;P&gt;(&amp;mut self, predicate: P) -&gt; Option&lt;Self::Item&gt;
    where
        P: FnMut(&amp;Self::Item) -&gt; bool;
    fn find_map&lt;B, F&gt;(&amp;mut self, f: F) -&gt; Option&lt;B&gt;
    where
        F: FnMut(Self::Item) -&gt; Option&lt;B&gt;;
    fn try_find&lt;F, R&gt;(
        &amp;mut self, 
        f: F
    ) -&gt; Result&lt;Option&lt;Self::Item&gt;, &lt;R as Try&gt;::Error&gt;
    where
        F: FnMut(&amp;Self::Item) -&gt; R,
        R: Try&lt;Ok = bool&gt;;
    fn position&lt;P&gt;(&amp;mut self, predicate: P) -&gt; Option&lt;usize&gt;
    where
        P: FnMut(Self::Item) -&gt; bool;
    fn rposition&lt;P&gt;(&amp;mut self, predicate: P) -&gt; Option&lt;usize&gt;
    where
        Self: ExactSizeIterator + DoubleEndedIterator,
        P: FnMut(Self::Item) -&gt; bool;
    fn max(self) -&gt; Option&lt;Self::Item&gt;
    where
        Self::Item: Ord;
    fn min(self) -&gt; Option&lt;Self::Item&gt;
    where
        Self::Item: Ord;
    fn max_by_key&lt;B, F&gt;(self, f: F) -&gt; Option&lt;Self::Item&gt;
    where
        F: FnMut(&amp;Self::Item) -&gt; B,
        B: Ord;
    fn max_by&lt;F&gt;(self, compare: F) -&gt; Option&lt;Self::Item&gt;
    where
        F: FnMut(&amp;Self::Item, &amp;Self::Item) -&gt; Ordering;
    fn min_by_key&lt;B, F&gt;(self, f: F) -&gt; Option&lt;Self::Item&gt;
    where
        F: FnMut(&amp;Self::Item) -&gt; B,
        B: Ord;
    fn min_by&lt;F&gt;(self, compare: F) -&gt; Option&lt;Self::Item&gt;
    where
        F: FnMut(&amp;Self::Item, &amp;Self::Item) -&gt; Ordering;
    fn rev(self) -&gt; Rev&lt;Self&gt;
    where
        Self: DoubleEndedIterator;
    fn unzip&lt;A, B, FromA, FromB&gt;(self) -&gt; (FromA, FromB)
    where
        Self: Iterator&lt;Item = (A, B)&gt;,
        FromA: Default + Extend&lt;A&gt;,
        FromB: Default + Extend&lt;B&gt;;
    fn copied&lt;'a, T&gt;(self) -&gt; Copied&lt;Self&gt;
    where
        Self: Iterator&lt;Item = &amp;'a T&gt;,
        T: 'a + Copy;
    fn cloned&lt;'a, T&gt;(self) -&gt; Cloned&lt;Self&gt;
    where
        Self: Iterator&lt;Item = &amp;'a T&gt;,
        T: 'a + Clone;
    fn cycle(self) -&gt; Cycle&lt;Self&gt;
    where
        Self: Clone;
    fn sum&lt;S&gt;(self) -&gt; S
    where
        S: Sum&lt;Self::Item&gt;;
    fn product&lt;P&gt;(self) -&gt; P
    where
        P: Product&lt;Self::Item&gt;;
    fn cmp&lt;I&gt;(self, other: I) -&gt; Ordering
    where
        I: IntoIterator&lt;Item = Self::Item&gt;,
        Self::Item: Ord;
    fn cmp_by&lt;I, F&gt;(self, other: I, cmp: F) -&gt; Ordering
    where
        F: FnMut(Self::Item, &lt;I as IntoIterator&gt;::Item) -&gt; Ordering,
        I: IntoIterator;
    fn partial_cmp&lt;I&gt;(self, other: I) -&gt; Option&lt;Ordering&gt;
    where
        I: IntoIterator,
        Self::Item: PartialOrd&lt;&lt;I as IntoIterator&gt;::Item&gt;;
    fn partial_cmp_by&lt;I, F&gt;(
        self, 
        other: I, 
        partial_cmp: F
    ) -&gt; Option&lt;Ordering&gt;
    where
        F: FnMut(Self::Item, &lt;I as IntoIterator&gt;::Item) -&gt; Option&lt;Ordering&gt;,
        I: IntoIterator;
    fn eq&lt;I&gt;(self, other: I) -&gt; bool
    where
        I: IntoIterator,
        Self::Item: PartialEq&lt;&lt;I as IntoIterator&gt;::Item&gt;;
    fn eq_by&lt;I, F&gt;(self, other: I, eq: F) -&gt; bool
    where
        F: FnMut(Self::Item, &lt;I as IntoIterator&gt;::Item) -&gt; bool,
        I: IntoIterator;
    fn ne&lt;I&gt;(self, other: I) -&gt; bool
    where
        I: IntoIterator,
        Self::Item: PartialEq&lt;&lt;I as IntoIterator&gt;::Item&gt;;
    fn lt&lt;I&gt;(self, other: I) -&gt; bool
    where
        I: IntoIterator,
        Self::Item: PartialOrd&lt;&lt;I as IntoIterator&gt;::Item&gt;;
    fn le&lt;I&gt;(self, other: I) -&gt; bool
    where
        I: IntoIterator,
        Self::Item: PartialOrd&lt;&lt;I as IntoIterator&gt;::Item&gt;;
    fn gt&lt;I&gt;(self, other: I) -&gt; bool
    where
        I: IntoIterator,
        Self::Item: PartialOrd&lt;&lt;I as IntoIterator&gt;::Item&gt;;
    fn ge&lt;I&gt;(self, other: I) -&gt; bool
    where
        I: IntoIterator,
        Self::Item: PartialOrd&lt;&lt;I as IntoIterator&gt;::Item&gt;;
    fn is_sorted(self) -&gt; bool
    where
        Self::Item: PartialOrd&lt;Self::Item&gt;;
    fn is_sorted_by&lt;F&gt;(self, compare: F) -&gt; bool
    where
        F: FnMut(&amp;Self::Item, &amp;Self::Item) -&gt; Option&lt;Ordering&gt;;
    fn is_sorted_by_key&lt;F, K&gt;(self, f: F) -&gt; bool
    where
        F: FnMut(Self::Item) -&gt; K,
        K: PartialOrd&lt;K&gt;;
}
<span class="boring">}
</span></code></pre></pre>
<p><code>Iterator&lt;Item = T&gt;</code> types can be iterated and will produce <code>T</code> types. There's no <code>IteratorMut</code> trait. Each <code>Iterator</code> impl can specify whether it returns immutable references, mutable references, or owned values via the <code>Item</code> associated type.</p>
<div class="table-wrapper"><table><thead><tr><th><code>Vec&lt;T&gt;</code> method</th><th>Returns</th></tr></thead><tbody>
<tr><td><code>.iter()</code></td><td><code>Iterator&lt;Item = &amp;T&gt;</code></td></tr>
<tr><td><code>.iter_mut()</code></td><td><code>Iterator&lt;Item = &amp;mut T&gt;</code></td></tr>
<tr><td><code>.into_iter()</code></td><td><code>Iterator&lt;Item = T&gt;</code></td></tr>
</tbody></table>
</div>
<p>Something that is not immediately obvious to beginner Rustaceans but that intermediate Rustaceans take for granted is that most types are not their own iterators. If a type is iterable we almost always impl some custom iterator type which iterates over it rather than trying to make it iterate over itself:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct MyType {
    items: Vec&lt;String&gt;
}

impl MyType {
    fn iter(&amp;self) -&gt; impl Iterator&lt;Item = &amp;String&gt; {
        MyTypeIterator {
            index: 0,
            items: &amp;self.items
        }
    }
}

struct MyTypeIterator&lt;'a&gt; {
    index: usize,
    items: &amp;'a Vec&lt;String&gt;
}

impl&lt;'a&gt; Iterator for MyTypeIterator&lt;'a&gt; {
    type Item = &amp;'a String;
    fn next(&amp;mut self) -&gt; Option&lt;Self::Item&gt; {
        if self.index &gt;= self.items.len() {
            None
        } else {
            let item = &amp;self.items[self.index];
            self.index += 1;
            Some(item)
        }
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>For the sake of teaching the above example shows how to impl an <code>Iterator</code> from scratch but the idiomatic solution in this situation would be to just defer to <code>Vec</code>'s <code>iter</code> method:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct MyType {
    items: Vec&lt;String&gt;
}

impl MyType {
    fn iter(&amp;self) -&gt; impl Iterator&lt;Item = &amp;String&gt; {
        self.items.iter()
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>Also this is a good generic blanket impl to be aware of:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>impl&lt;I: Iterator + ?Sized&gt; Iterator for &amp;mut I;
<span class="boring">}
</span></code></pre></pre>
<p>It says that any mutable reference to an iterator is also an iterator. This is useful to know because it allows us to use iterator methods with <code>self</code> receivers as if they had <code>&amp;mut self</code> receivers.</p>
<p>As an example, imagine we have a function which processes an iterator of more than three items, but the first step of the function is to take out the first three items of the iterator and process them separately before iterating over the remaining items, here's how a beginner may attempt to write this function:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn example&lt;I: Iterator&lt;Item = i32&gt;&gt;(mut iter: I) {
    let first3: Vec&lt;i32&gt; = iter.take(3).collect();
    for item in iter { // ❌ iter consumed in line above
        // process remaining items
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>Well that's annoying. The <code>take</code> method has a <code>self</code> receiver so it seems like we cannot call it without consuming the whole iterator! Here's what a naive refactor of the above code might look like:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn example&lt;I: Iterator&lt;Item = i32&gt;&gt;(mut iter: I) {
    let first3: Vec&lt;i32&gt; = vec![
        iter.next().unwrap(),
        iter.next().unwrap(),
        iter.next().unwrap(),
    ];
    for item in iter { // ✅
        // process remaining items
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>Which is okay. However, the idiomatic refactor is actually:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn example&lt;I: Iterator&lt;Item = i32&gt;&gt;(mut iter: I) {
    let first3: Vec&lt;i32&gt; = iter.by_ref().take(3).collect();
    for item in iter { // ✅
        // process remaining items
    }
}
<span class="boring">}
</span></code></pre></pre>
<p>Not very easy to discover. But anyway, now we know.</p>
<p>Also, there are no rules or conventions on what can or cannot be an iterator. If the type impls <code>Iterator</code> then it's an iterator. Some creative examples from the standard library:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::sync::mpsc::channel;
use std::thread;

fn paths_can_be_iterated(path: &amp;Path) {
    for part in path {
        // iterate over parts of a path
    }
}

fn receivers_can_be_iterated() {
    let (send, recv) = channel();

    thread::spawn(move || {
        send.send(1).unwrap();
        send.send(2).unwrap();
        send.send(3).unwrap();
    });

    for received in recv {
        // iterate over received values
    }
}
<span class="boring">}
</span></code></pre></pre>
<h3 id="intoiterator"><a class="header" href="#intoiterator">IntoIterator</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#associated-types">Associated Types</a></li>
<li><a href="#iterator">Iterator</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait IntoIterator 
where
    &lt;Self::IntoIter as Iterator&gt;::Item == Self::Item, 
{
    type Item;
    type IntoIter: Iterator;
    fn into_iter(self) -&gt; Self::IntoIter;
}
<span class="boring">}
</span></code></pre></pre>
<p><code>IntoIterator</code> types can be converted into iterators, hence the name. The <code>into_iter</code> method is called on a type when it's used within a <code>for-in</code> loop:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// vec = Vec&lt;T&gt;
for v in vec {} // v = T

// above line desugared
for v in vec.into_iter() {}
<span class="boring">}
</span></code></pre></pre>
<p>Not only does <code>Vec</code> impl <code>IntoIterator</code> but so does <code>&amp;Vec</code> and <code>&amp;mut Vec</code> if we'd like to iterate over immutable or mutable references instead of owned values, respectively.</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// vec = Vec&lt;T&gt;
for v in &amp;vec {} // v = &amp;T

// above example desugared
for v in (&amp;vec).into_iter() {}

// vec = Vec&lt;T&gt;
for v in &amp;mut vec {} // v = &amp;mut T

// above example desugared
for v in (&amp;mut vec).into_iter() {}
<span class="boring">}
</span></code></pre></pre>
<h3 id="fromiterator"><a class="header" href="#fromiterator">FromIterator</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#functions">Functions</a></li>
<li><a href="#generic-parameters">Generic Parameters</a></li>
<li><a href="#iterator">Iterator</a></li>
<li><a href="#intoiterator">IntoIterator</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait FromIterator&lt;A&gt; {
    fn from_iter&lt;T&gt;(iter: T) -&gt; Self
    where
        T: IntoIterator&lt;Item = A&gt;;
}
<span class="boring">}
</span></code></pre></pre>
<p><code>FromIterator</code> types can be created from an iterator, hence the name. <code>FromIterator</code> is most commonly and idiomatically used by calling the <code>collect</code> method on <code>Iterator</code>:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn collect&lt;B&gt;(self) -&gt; B
where
    B: FromIterator&lt;Self::Item&gt;;
<span class="boring">}
</span></code></pre></pre>
<p>Example of collecting an <code>Iterator&lt;Item = char&gt;</code> into a <code>String</code>:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>fn filter_letters(string: &amp;str) -&gt; String {
    string.chars().filter(|c| c.is_alphabetic()).collect()
}
<span class="boring">}
</span></code></pre></pre>
<p>All the collections in the standard library impl <code>IntoIterator</code> and <code>FromIterator</code> so that makes it easier to convert between them:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::collections::{BTreeSet, HashMap, HashSet, LinkedList};

// String -&gt; HashSet&lt;char&gt;
fn unique_chars(string: &amp;str) -&gt; HashSet&lt;char&gt; {
    string.chars().collect()
}

// Vec&lt;T&gt; -&gt; BTreeSet&lt;T&gt;
fn ordered_unique_items&lt;T: Ord&gt;(vec: Vec&lt;T&gt;) -&gt; BTreeSet&lt;T&gt; {
    vec.into_iter().collect()
}

// HashMap&lt;K, V&gt; -&gt; LinkedList&lt;(K, V)&gt;
fn entry_list&lt;K, V&gt;(map: HashMap&lt;K, V&gt;) -&gt; LinkedList&lt;(K, V)&gt; {
    map.into_iter().collect()
}

// and countless more possible examples
<span class="boring">}
</span></code></pre></pre>
<h2 id="io-traits"><a class="header" href="#io-traits">I/O Traits</a></h2>
<h3 id="read--write"><a class="header" href="#read--write">Read &amp; Write</a></h3>
<p>Prerequisites</p>
<ul>
<li><a href="#self">Self</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#scope">Scope</a></li>
<li><a href="#generic-blanket-impls">Generic Blanket Impls</a></li>
</ul>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>trait Read {
    fn read(&amp;mut self, buf: &amp;mut [u8]) -&gt; Result&lt;usize&gt;;

    // provided default impls
    fn read_vectored(&amp;mut self, bufs: &amp;mut [IoSliceMut&lt;'_&gt;]) -&gt; Result&lt;usize&gt;;
    fn is_read_vectored(&amp;self) -&gt; bool;
    unsafe fn initializer(&amp;self) -&gt; Initializer;
    fn read_to_end(&amp;mut self, buf: &amp;mut Vec&lt;u8&gt;) -&gt; Result&lt;usize&gt;;
    fn read_to_string(&amp;mut self, buf: &amp;mut String) -&gt; Result&lt;usize&gt;;
    fn read_exact(&amp;mut self, buf: &amp;mut [u8]) -&gt; Result&lt;()&gt;;
    fn by_ref(&amp;mut self) -&gt; &amp;mut Self
    where
        Self: Sized;
    fn bytes(self) -&gt; Bytes&lt;Self&gt;
    where
        Self: Sized;
    fn chain&lt;R: Read&gt;(self, next: R) -&gt; Chain&lt;Self, R&gt;
    where
        Self: Sized;
    fn take(self, limit: u64) -&gt; Take&lt;Self&gt;
    where
        Self: Sized;
}

trait Write {
    fn write(&amp;mut self, buf: &amp;[u8]) -&gt; Result&lt;usize&gt;;
    fn flush(&amp;mut self) -&gt; Result&lt;()&gt;;

    // provided default impls
    fn write_vectored(&amp;mut self, bufs: &amp;[IoSlice&lt;'_&gt;]) -&gt; Result&lt;usize&gt;;
    fn is_write_vectored(&amp;self) -&gt; bool;
    fn write_all(&amp;mut self, buf: &amp;[u8]) -&gt; Result&lt;()&gt;;
    fn write_all_vectored(&amp;mut self, bufs: &amp;mut [IoSlice&lt;'_&gt;]) -&gt; Result&lt;()&gt;;
    fn write_fmt(&amp;mut self, fmt: Arguments&lt;'_&gt;) -&gt; Result&lt;()&gt;;
    fn by_ref(&amp;mut self) -&gt; &amp;mut Self
    where
        Self: Sized;
}
<span class="boring">}
</span></code></pre></pre>
<p>Generic blanket impls worth knowing:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>impl&lt;R: Read + ?Sized&gt; Read for &amp;mut R;
impl&lt;W: Write + ?Sized&gt; Write for &amp;mut W;
<span class="boring">}
</span></code></pre></pre>
<p>These say that any mutable reference to a <code>Read</code> type is also <code>Read</code>, and same with <code>Write</code>. This is useful to know because it allows us to use any method with a <code>self</code> receiver as if it had a <code>&amp;mut self</code> receiver. We already went over how to do this and why it's useful in the <code>Iterator</code> trait section so I'm not going to repeat it again here.</p>
<p>I'd like to point out that <code>&amp;[u8]</code> impls <code>Read</code> and that <code>Vec&lt;u8&gt;</code> impls <code>Write</code> so we can easily unit test our file handling functions using <code>String</code>s which are trivial to convert to <code>&amp;[u8]</code> and from <code>Vec&lt;u8&gt;</code>:</p>
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::path::Path;
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::io;

// function we want to test
fn uppercase&lt;R: Read, W: Write&gt;(mut read: R, mut write: W) -&gt; Result&lt;(), io::Error&gt; {
    let mut buffer = String::new();
    read.read_to_string(&amp;mut buffer)?;
    let uppercase = buffer.to_uppercase();
    write.write_all(uppercase.as_bytes())?;
    write.flush()?;
    Ok(())
}

// in actual program we'd pass Files
fn example(in_path: &amp;Path, out_path: &amp;Path) -&gt; Result&lt;(), io::Error&gt; {
    let in_file = File::open(in_path)?;
    let out_file = File::open(out_path)?;
    uppercase(in_file, out_file)
}


// however in unit tests we can use Strings!
#[test] // ✅
fn example_test() {
    let in_file: String = &quot;i am screaming&quot;.into();
    let mut out_file: Vec&lt;u8&gt; = Vec::new();
    uppercase(in_file.as_bytes(), &amp;mut out_file).unwrap();
    let out_result = String::from_utf8(out_file).unwrap();
    assert_eq!(out_result, &quot;I AM SCREAMING&quot;);
}
<span class="boring">}
</span></code></pre></pre>
<h2 id="conclusion"><a class="header" href="#conclusion">Conclusion</a></h2>
<p>We learned a lot together! Too much in fact. This is us now:</p>
<p><img src="C:/Users/ADMINI~1/AppData/Local/Temp/assets/jason-jarvis-stdlib-traits.png" alt="rust standard library traits" /></p>
<p><em>Artist credit: <a href="https://thejenkinscomic.wordpress.com/2020/05/06/memory/">The Jenkins Comic</a></em></p>
<h2 id="discuss"><a class="header" href="#discuss">Discuss</a></h2>
<p>Discuss this article on</p>
<ul>
<li><a href="https://github.com/pretzelhammer/rust-blog/discussions">Github</a></li>
<li><a href="https://www.reddit.com/r/learnrust/comments/ml9shl/tour_of_rusts_standard_library_traits/">learnrust subreddit</a></li>
<li><a href="https://users.rust-lang.org/t/blog-post-tour-of-rusts-standard-library-traits/57974">official Rust users forum</a></li>
<li><a href="https://twitter.com/pretzelhammer/status/1379561720176336902">Twitter</a></li>
<li><a href="https://lobste.rs/s/g27ezp/tour_rust_s_standard_library_traits">lobste.rs</a></li>
<li><a href="https://www.reddit.com/r/rust/comments/mmrao0/tour_of_rusts_standard_library_traits/">rust subreddit</a></li>
</ul>
<h2 id="notifications"><a class="header" href="#notifications">Notifications</a></h2>
<p>Get notified when the next article get published by</p>
<ul>
<li><a href="https://twitter.com/pretzelhammer">Following pretzelhammer on Twitter</a> or</li>
<li><a href="https://github.com/pretzelhammer/rust-blog/releases.atom">Subscribing to this repo's release RSS feed</a> or</li>
<li>Watching this repo's releases (click <code>Watch</code> -&gt; click <code>Custom</code> -&gt; select <code>Releases</code> -&gt; click <code>Apply</code>)</li>
</ul>
<h2 id="further-reading"><a class="header" href="#further-reading">Further Reading</a></h2>
<ul>
<li><a href="./sizedness-in-rust.html">Sizedness in Rust</a></li>
<li><a href="./common-rust-lifetime-misconceptions.html">Common Rust Lifetime Misconceptions</a></li>
<li><a href="./restful-api-in-sync-and-async-rust.html">RESTful API in Sync &amp; Async Rust</a></li>
<li><a href="./learning-rust-in-2020.html">Learning Rust in 2020</a></li>
<li><a href="./too-many-brainfuck-compilers.html">Learn Assembly with Entirely Too Many Brainfuck Compilers</a></li>
</ul>

                    </main>

                    <nav class="nav-wrapper" aria-label="Page navigation">
                        <!-- Mobile navigation buttons -->
                            <a rel="prev" href="../../01_类型系统/一行代码告诉你内部可变性的真相(UnsafeCell)/一行代码告诉你内部可变性的真相(UnsafeCell).html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                                <i class="fa fa-angle-left"></i>
                            </a>

                            <a rel="next" href="../../01_类型系统/逆变、协变与子类型，以及Rust/逆变、协变与子类型，以及Rust.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                                <i class="fa fa-angle-right"></i>
                            </a>

                        <div style="clear: both"></div>
                    </nav>
                </div>
            </div>

            <nav class="nav-wide-wrapper" aria-label="Page navigation">
                    <a rel="prev" href="../../01_类型系统/一行代码告诉你内部可变性的真相(UnsafeCell)/一行代码告诉你内部可变性的真相(UnsafeCell).html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                        <i class="fa fa-angle-left"></i>
                    </a>

                    <a rel="next" href="../../01_类型系统/逆变、协变与子类型，以及Rust/逆变、协变与子类型，以及Rust.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                        <i class="fa fa-angle-right"></i>
                    </a>
            </nav>

        </div>




        <script type="text/javascript">
            window.playground_copyable = true;
        </script>


        <script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../../searcher.js" type="text/javascript" charset="utf-8"></script>

        <script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../../highlight.js" type="text/javascript" charset="utf-8"></script>
        <script src="../../book.js" type="text/javascript" charset="utf-8"></script>

        <!-- Custom JS scripts -->


    </body>
</html>
